[media] drx-j: CodingStyle fixes
[deliverable/linux.git] / drivers / media / dvb-frontends / drx39xyj / drxj.c
1 /*
2 Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Trident Microsystems nor Hauppauge Computer Works
14 nor the names of its contributors may be used to endorse or promote
15 products derived from this software without specific prior written
16 permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
32 * \file $Id: drxj.c,v 1.637 2010/01/18 17:21:10 dingtao Exp $
33 *
34 * \brief DRXJ specific implementation of DRX driver
35 *
36 * \author Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
37 */
38
39 /*-----------------------------------------------------------------------------
40 INCLUDE FILES
41 ----------------------------------------------------------------------------*/
42
43 #include "drxj.h"
44 #include "drxj_map.h"
45
46 #ifdef DRXJ_OPTIONS_H
47 #include "drxj_options.h"
48 #endif
49
50 /*============================================================================*/
51 /*=== DEFINES ================================================================*/
52 /*============================================================================*/
53
54 /**
55 * \brief Maximum u32_t value.
56 */
57 #ifndef MAX_U32
58 #define MAX_U32 ((u32_t) (0xFFFFFFFFL))
59 #endif
60
61 /* Customer configurable hardware settings, etc */
62 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
63 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
64 #endif
65
66 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
67 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
68 #endif
69
70 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
71 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
72 #endif
73
74 #ifndef OOB_CRX_DRIVE_STRENGTH
75 #define OOB_CRX_DRIVE_STRENGTH 0x02
76 #endif
77
78 #ifndef OOB_DRX_DRIVE_STRENGTH
79 #define OOB_DRX_DRIVE_STRENGTH 0x02
80 #endif
81 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
82 /**** registermap 200706071303 from drxj **************************************/
83 #define ATV_TOP_CR_AMP_TH_FM 0x0
84 #define ATV_TOP_CR_AMP_TH_L 0xA
85 #define ATV_TOP_CR_AMP_TH_LP 0xA
86 #define ATV_TOP_CR_AMP_TH_BG 0x8
87 #define ATV_TOP_CR_AMP_TH_DK 0x8
88 #define ATV_TOP_CR_AMP_TH_I 0x8
89 #define ATV_TOP_CR_CONT_CR_D_MN 0x18
90 #define ATV_TOP_CR_CONT_CR_D_FM 0x0
91 #define ATV_TOP_CR_CONT_CR_D_L 0x20
92 #define ATV_TOP_CR_CONT_CR_D_LP 0x20
93 #define ATV_TOP_CR_CONT_CR_D_BG 0x18
94 #define ATV_TOP_CR_CONT_CR_D_DK 0x18
95 #define ATV_TOP_CR_CONT_CR_D_I 0x18
96 #define ATV_TOP_CR_CONT_CR_I_MN 0x80
97 #define ATV_TOP_CR_CONT_CR_I_FM 0x0
98 #define ATV_TOP_CR_CONT_CR_I_L 0x80
99 #define ATV_TOP_CR_CONT_CR_I_LP 0x80
100 #define ATV_TOP_CR_CONT_CR_I_BG 0x80
101 #define ATV_TOP_CR_CONT_CR_I_DK 0x80
102 #define ATV_TOP_CR_CONT_CR_I_I 0x80
103 #define ATV_TOP_CR_CONT_CR_P_MN 0x4
104 #define ATV_TOP_CR_CONT_CR_P_FM 0x0
105 #define ATV_TOP_CR_CONT_CR_P_L 0x4
106 #define ATV_TOP_CR_CONT_CR_P_LP 0x4
107 #define ATV_TOP_CR_CONT_CR_P_BG 0x4
108 #define ATV_TOP_CR_CONT_CR_P_DK 0x4
109 #define ATV_TOP_CR_CONT_CR_P_I 0x4
110 #define ATV_TOP_CR_OVM_TH_MN 0xA0
111 #define ATV_TOP_CR_OVM_TH_FM 0x0
112 #define ATV_TOP_CR_OVM_TH_L 0xA0
113 #define ATV_TOP_CR_OVM_TH_LP 0xA0
114 #define ATV_TOP_CR_OVM_TH_BG 0xA0
115 #define ATV_TOP_CR_OVM_TH_DK 0xA0
116 #define ATV_TOP_CR_OVM_TH_I 0xA0
117 #define ATV_TOP_EQU0_EQU_C0_FM 0x0
118 #define ATV_TOP_EQU0_EQU_C0_L 0x3
119 #define ATV_TOP_EQU0_EQU_C0_LP 0x3
120 #define ATV_TOP_EQU0_EQU_C0_BG 0x7
121 #define ATV_TOP_EQU0_EQU_C0_DK 0x0
122 #define ATV_TOP_EQU0_EQU_C0_I 0x3
123 #define ATV_TOP_EQU1_EQU_C1_FM 0x0
124 #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
125 #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
126 #define ATV_TOP_EQU1_EQU_C1_BG 0x197
127 #define ATV_TOP_EQU1_EQU_C1_DK 0x198
128 #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
129 #define ATV_TOP_EQU2_EQU_C2_FM 0x0
130 #define ATV_TOP_EQU2_EQU_C2_L 0x28
131 #define ATV_TOP_EQU2_EQU_C2_LP 0x28
132 #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
133 #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
134 #define ATV_TOP_EQU2_EQU_C2_I 0x28
135 #define ATV_TOP_EQU3_EQU_C3_FM 0x0
136 #define ATV_TOP_EQU3_EQU_C3_L 0x192
137 #define ATV_TOP_EQU3_EQU_C3_LP 0x192
138 #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
139 #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
140 #define ATV_TOP_EQU3_EQU_C3_I 0x192
141 #define ATV_TOP_STD_MODE_MN 0x0
142 #define ATV_TOP_STD_MODE_FM 0x1
143 #define ATV_TOP_STD_MODE_L 0x0
144 #define ATV_TOP_STD_MODE_LP 0x0
145 #define ATV_TOP_STD_MODE_BG 0x0
146 #define ATV_TOP_STD_MODE_DK 0x0
147 #define ATV_TOP_STD_MODE_I 0x0
148 #define ATV_TOP_STD_VID_POL_MN 0x0
149 #define ATV_TOP_STD_VID_POL_FM 0x0
150 #define ATV_TOP_STD_VID_POL_L 0x2
151 #define ATV_TOP_STD_VID_POL_LP 0x2
152 #define ATV_TOP_STD_VID_POL_BG 0x0
153 #define ATV_TOP_STD_VID_POL_DK 0x0
154 #define ATV_TOP_STD_VID_POL_I 0x0
155 #define ATV_TOP_VID_AMP_MN 0x380
156 #define ATV_TOP_VID_AMP_FM 0x0
157 #define ATV_TOP_VID_AMP_L 0xF50
158 #define ATV_TOP_VID_AMP_LP 0xF50
159 #define ATV_TOP_VID_AMP_BG 0x380
160 #define ATV_TOP_VID_AMP_DK 0x394
161 #define ATV_TOP_VID_AMP_I 0x3D8
162 #define IQM_CF_OUT_ENA_OFDM__M 0x4
163 #define IQM_FS_ADJ_SEL_B_QAM 0x1
164 #define IQM_FS_ADJ_SEL_B_OFF 0x0
165 #define IQM_FS_ADJ_SEL_B_VSB 0x2
166 #define IQM_RC_ADJ_SEL_B_OFF 0x0
167 #define IQM_RC_ADJ_SEL_B_QAM 0x1
168 #define IQM_RC_ADJ_SEL_B_VSB 0x2
169 /**** END DJCOMBO patches to DRXJ registermap *********************************/
170
171 #include "drx_driver_version.h"
172
173 //#define DRX_DEBUG
174 #ifdef DRX_DEBUG
175 #include <stdio.h>
176 #endif
177
178 /*-----------------------------------------------------------------------------
179 ENUMS
180 ----------------------------------------------------------------------------*/
181
182 /*-----------------------------------------------------------------------------
183 DEFINES
184 ----------------------------------------------------------------------------*/
185 #ifndef DRXJ_WAKE_UP_KEY
186 #define DRXJ_WAKE_UP_KEY (demod -> myI2CDevAddr -> i2cAddr)
187 #endif
188
189 /**
190 * \def DRXJ_DEF_I2C_ADDR
191 * \brief Default I2C addres of a demodulator instance.
192 */
193 #define DRXJ_DEF_I2C_ADDR (0x52)
194
195 /**
196 * \def DRXJ_DEF_DEMOD_DEV_ID
197 * \brief Default device identifier of a demodultor instance.
198 */
199 #define DRXJ_DEF_DEMOD_DEV_ID (1)
200
201 /**
202 * \def DRXJ_SCAN_TIMEOUT
203 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
204 */
205 #define DRXJ_SCAN_TIMEOUT 1000
206
207 /**
208 * \def DRXJ_DAP
209 * \brief Name of structure containing all data access protocol functions.
210 */
211 #define DRXJ_DAP drxDapDRXJFunct_g
212
213 /**
214 * \def HI_I2C_DELAY
215 * \brief HI timing delay for I2C timing (in nano seconds)
216 *
217 * Used to compute HI_CFG_DIV
218 */
219 #define HI_I2C_DELAY 42
220
221 /**
222 * \def HI_I2C_BRIDGE_DELAY
223 * \brief HI timing delay for I2C timing (in nano seconds)
224 *
225 * Used to compute HI_CFG_BDL
226 */
227 #define HI_I2C_BRIDGE_DELAY 750
228
229 /**
230 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
231 */
232 #define VSB_TOP_MEASUREMENT_PERIOD 64
233 #define SYMBOLS_PER_SEGMENT 832
234
235 /**
236 * \brief bit rate and segment rate constants used for SER and BER.
237 */
238 /* values taken from the QAM microcode */
239 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
240 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
241 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
242 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
243 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
244 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
245 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
246 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
247 /**
248 * \brief Min supported symbolrates.
249 */
250 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
251 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
252 #endif
253
254 /**
255 * \brief Max supported symbolrates.
256 */
257 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
258 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
259 #endif
260
261 /**
262 * \def DRXJ_QAM_MAX_WAITTIME
263 * \brief Maximal wait time for QAM auto constellation in ms
264 */
265 #ifndef DRXJ_QAM_MAX_WAITTIME
266 #define DRXJ_QAM_MAX_WAITTIME 900
267 #endif
268
269 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
270 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
271 #endif
272
273 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
274 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
275 #endif
276
277 /**
278 * \def SCU status and results
279 * \brief SCU
280 */
281 #define DRX_SCU_READY 0
282 #define DRXJ_MAX_WAITTIME 100 /* ms */
283 #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
284 #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
285
286 /**
287 * \def DRX_AUD_MAX_DEVIATION
288 * \brief Needed for calculation of prescale feature in AUD
289 */
290 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
291 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
292 #endif
293
294 /**
295 * \brief Needed for calculation of NICAM prescale feature in AUD
296 */
297 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
298 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
299 #endif
300
301 /**
302 * \brief Needed for calculation of NICAM prescale feature in AUD
303 */
304 #ifndef DRXJ_AUD_MAX_WAITTIME
305 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
306 #endif
307
308 /* ATV config changed flags */
309 #define DRXJ_ATV_CHANGED_COEF ( 0x00000001UL )
310 #define DRXJ_ATV_CHANGED_PEAK_FLT ( 0x00000008UL )
311 #define DRXJ_ATV_CHANGED_NOISE_FLT ( 0x00000010UL )
312 #define DRXJ_ATV_CHANGED_OUTPUT ( 0x00000020UL )
313 #define DRXJ_ATV_CHANGED_SIF_ATT ( 0x00000040UL )
314
315 /* UIO define */
316 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
317 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
318
319 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
320 /*============================================================================*/
321 /*=== MICROCODE RELATED DEFINES ==============================================*/
322 /*============================================================================*/
323
324 /**
325 * \def DRXJ_UCODE_MAGIC_WORD
326 * \brief Magic word for checking correct Endianess of microcode data.
327 *
328 */
329
330 #ifndef DRXJ_UCODE_MAGIC_WORD
331 #define DRXJ_UCODE_MAGIC_WORD ((((u16_t)'H')<<8)+((u16_t)'L'))
332 #endif
333
334 /**
335 * \def DRXJ_UCODE_CRC_FLAG
336 * \brief CRC flag in ucode header, flags field.
337 *
338 */
339
340 #ifndef DRXJ_UCODE_CRC_FLAG
341 #define DRXJ_UCODE_CRC_FLAG (0x0001)
342 #endif
343
344 /**
345 * \def DRXJ_UCODE_COMPRESSION_FLAG
346 * \brief Compression flag in ucode header, flags field.
347 *
348 */
349
350 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
351 #define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
352 #endif
353
354 /**
355 * \def DRXJ_UCODE_MAX_BUF_SIZE
356 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
357 *
358 */
359
360 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
361 #define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
362 #endif
363 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
364 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
365 #endif
366
367 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
368
369 /* Pin safe mode macro */
370 #define DRXJ_PIN_SAFE_MODE 0x0000
371 /*============================================================================*/
372 /*=== GLOBAL VARIABLEs =======================================================*/
373 /*============================================================================*/
374 /**
375 */
376
377 /**
378 * \brief Temporary register definitions.
379 * (register definitions that are not yet available in register master)
380 */
381
382 /******************************************************************************/
383 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
384 /* RAM adresses directly. This must be READ ONLY to avoid problems. */
385 /* Writing to the interface adresses is more than only writing the RAM */
386 /* locations */
387 /******************************************************************************/
388 /**
389 * \brief RAM location of MODUS registers
390 */
391 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
392 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
393
394 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
395 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
396
397 /**
398 * \brief RAM location of I2S config registers
399 */
400 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
401 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
402
403 /**
404 * \brief RAM location of DCO config registers
405 */
406 #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
407 #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
408 #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
409 #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
410
411 /**
412 * \brief RAM location of Threshold registers
413 */
414 #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
415 #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
416 #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
417
418 /**
419 * \brief RAM location of Carrier Threshold registers
420 */
421 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
422 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
423
424 /**
425 * \brief FM Matrix register fix
426 */
427 #ifdef AUD_DEM_WR_FM_MATRIX__A
428 #undef AUD_DEM_WR_FM_MATRIX__A
429 #endif
430 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
431
432 /*============================================================================*/
433 /**
434 * \brief Defines required for audio
435 */
436 #define AUD_VOLUME_ZERO_DB 115
437 #define AUD_VOLUME_DB_MIN -60
438 #define AUD_VOLUME_DB_MAX 12
439 #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
440 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
441 #define AUD_MAX_AVC_REF_LEVEL 15
442 #define AUD_I2S_FREQUENCY_MAX 48000UL
443 #define AUD_I2S_FREQUENCY_MIN 12000UL
444 #define AUD_RDS_ARRAY_SIZE 18
445
446 /**
447 * \brief Needed for calculation of prescale feature in AUD
448 */
449 #ifndef DRX_AUD_MAX_FM_DEVIATION
450 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
451 #endif
452
453 /**
454 * \brief Needed for calculation of NICAM prescale feature in AUD
455 */
456 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
457 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
458 #endif
459
460 /*============================================================================*/
461 /* Values for I2S Master/Slave pin configurations */
462 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
463 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
464 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
465 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
466
467 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
468 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
469 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
470 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
471
472 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
473 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
474 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
475 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
476
477 /*============================================================================*/
478 /*=== REGISTER ACCESS MACROS =================================================*/
479 /*============================================================================*/
480
481 #ifdef DRXJDRIVER_DEBUG
482 #include <stdio.h>
483 #define CHK_ERROR( s ) \
484 do{ \
485 if ( (s) != DRX_STS_OK ) \
486 { \
487 fprintf(stderr, \
488 "ERROR[\n file : %s\n line : %d\n]\n", \
489 __FILE__,__LINE__); \
490 goto rw_error; }; \
491 } \
492 while (0 != 0)
493 #else
494 #define CHK_ERROR( s ) \
495 do{ \
496 if ( (s) != DRX_STS_OK ) { goto rw_error; } \
497 } while (0 != 0)
498 #endif
499
500 #define CHK_ZERO( s ) \
501 do{ \
502 if ( (s) == 0 ) return DRX_STS_ERROR; \
503 } while (0)
504
505 #define DUMMY_READ() \
506 do{ \
507 u16_t dummy; \
508 RR16( demod->myI2CDevAddr, SCU_RAM_VERSION_HI__A, &dummy ); \
509 } while (0)
510
511 #define WR16( dev, addr, val) \
512 CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), 0 ) )
513
514 #define RR16( dev, addr, val) \
515 CHK_ERROR( DRXJ_DAP.readReg16Func( (dev), (addr), (val), 0 ) )
516
517 #define WR32( dev, addr, val) \
518 CHK_ERROR( DRXJ_DAP.writeReg32Func( (dev), (addr), (val), 0 ) )
519
520 #define RR32( dev, addr, val) \
521 CHK_ERROR( DRXJ_DAP.readReg32Func( (dev), (addr), (val), 0 ) )
522
523 #define WRB( dev, addr, len, block ) \
524 CHK_ERROR( DRXJ_DAP.writeBlockFunc( (dev), (addr), (len), (block), 0 ) )
525
526 #define RRB( dev, addr, len, block ) \
527 CHK_ERROR( DRXJ_DAP.readBlockFunc( (dev), (addr), (len), (block), 0 ) )
528
529 #define BCWR16( dev, addr, val ) \
530 CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), DRXDAP_FASI_BROADCAST ) )
531
532 #define ARR32( dev, addr, val) \
533 CHK_ERROR( DRXJ_DAP_AtomicReadReg32( (dev), (addr), (val), 0 ) )
534
535 #define SARR16( dev, addr, val) \
536 CHK_ERROR( DRXJ_DAP_SCU_AtomicReadReg16( (dev), (addr), (val), 0 ) )
537
538 #define SAWR16( dev, addr, val) \
539 CHK_ERROR( DRXJ_DAP_SCU_AtomicWriteReg16( (dev), (addr), (val), 0 ) )
540
541 /**
542 * This macro is used to create byte arrays for block writes.
543 * Block writes speed up I2C traffic between host and demod.
544 * The macro takes care of the required byte order in a 16 bits word.
545 * x -> lowbyte(x), highbyte(x)
546 */
547 #define DRXJ_16TO8( x ) ((u8_t) (((u16_t)x) &0xFF)), \
548 ((u8_t)((((u16_t)x)>>8)&0xFF))
549 /**
550 * This macro is used to convert byte array to 16 bit register value for block read.
551 * Block read speed up I2C traffic between host and demod.
552 * The macro takes care of the required byte order in a 16 bits word.
553 */
554 #define DRXJ_8TO16( x ) ((u16_t) (x[0] | (x[1] << 8)))
555
556 /*============================================================================*/
557 /*=== MISC DEFINES ===========================================================*/
558 /*============================================================================*/
559
560 /*============================================================================*/
561 /*=== HI COMMAND RELATED DEFINES =============================================*/
562 /*============================================================================*/
563
564 /**
565 * \brief General maximum number of retries for ucode command interfaces
566 */
567 #define DRXJ_MAX_RETRIES (100)
568
569 /*============================================================================*/
570 /*=== STANDARD RELATED MACROS ================================================*/
571 /*============================================================================*/
572
573 #define DRXJ_ISATVSTD( std ) ( ( std == DRX_STANDARD_PAL_SECAM_BG ) || \
574 ( std == DRX_STANDARD_PAL_SECAM_DK ) || \
575 ( std == DRX_STANDARD_PAL_SECAM_I ) || \
576 ( std == DRX_STANDARD_PAL_SECAM_L ) || \
577 ( std == DRX_STANDARD_PAL_SECAM_LP ) || \
578 ( std == DRX_STANDARD_NTSC ) || \
579 ( std == DRX_STANDARD_FM ) )
580
581 #define DRXJ_ISQAMSTD( std ) ( ( std == DRX_STANDARD_ITU_A ) || \
582 ( std == DRX_STANDARD_ITU_B ) || \
583 ( std == DRX_STANDARD_ITU_C ) || \
584 ( std == DRX_STANDARD_ITU_D ))
585
586 /*-----------------------------------------------------------------------------
587 STATIC VARIABLES
588 ----------------------------------------------------------------------------*/
589 DRXStatus_t DRXJ_Open(pDRXDemodInstance_t demod);
590 DRXStatus_t DRXJ_Close(pDRXDemodInstance_t demod);
591 DRXStatus_t DRXJ_Ctrl(pDRXDemodInstance_t demod,
592 DRXCtrlIndex_t ctrl, void *ctrlData);
593
594 /*-----------------------------------------------------------------------------
595 GLOBAL VARIABLES
596 ----------------------------------------------------------------------------*/
597 /*
598 * DRXJ DAP structures
599 */
600
601 static DRXStatus_t DRXJ_DAP_ReadBlock(pI2CDeviceAddr_t devAddr,
602 DRXaddr_t addr,
603 u16_t datasize,
604 pu8_t data, DRXflags_t flags);
605
606 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg8(pI2CDeviceAddr_t devAddr,
607 DRXaddr_t waddr,
608 DRXaddr_t raddr,
609 u8_t wdata, pu8_t rdata);
610
611 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg16(pI2CDeviceAddr_t devAddr,
612 DRXaddr_t waddr,
613 DRXaddr_t raddr,
614 u16_t wdata, pu16_t rdata);
615
616 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg32(pI2CDeviceAddr_t devAddr,
617 DRXaddr_t waddr,
618 DRXaddr_t raddr,
619 u32_t wdata, pu32_t rdata);
620
621 static DRXStatus_t DRXJ_DAP_ReadReg8(pI2CDeviceAddr_t devAddr,
622 DRXaddr_t addr,
623 pu8_t data, DRXflags_t flags);
624
625 static DRXStatus_t DRXJ_DAP_ReadReg16(pI2CDeviceAddr_t devAddr,
626 DRXaddr_t addr,
627 pu16_t data, DRXflags_t flags);
628
629 static DRXStatus_t DRXJ_DAP_ReadReg32(pI2CDeviceAddr_t devAddr,
630 DRXaddr_t addr,
631 pu32_t data, DRXflags_t flags);
632
633 static DRXStatus_t DRXJ_DAP_WriteBlock(pI2CDeviceAddr_t devAddr,
634 DRXaddr_t addr,
635 u16_t datasize,
636 pu8_t data, DRXflags_t flags);
637
638 static DRXStatus_t DRXJ_DAP_WriteReg8(pI2CDeviceAddr_t devAddr,
639 DRXaddr_t addr,
640 u8_t data, DRXflags_t flags);
641
642 static DRXStatus_t DRXJ_DAP_WriteReg16(pI2CDeviceAddr_t devAddr,
643 DRXaddr_t addr,
644 u16_t data, DRXflags_t flags);
645
646 static DRXStatus_t DRXJ_DAP_WriteReg32(pI2CDeviceAddr_t devAddr,
647 DRXaddr_t addr,
648 u32_t data, DRXflags_t flags);
649
650 /* The version structure of this protocol implementation */
651 char drxDapDRXJModuleName[] = "DRXJ Data Access Protocol";
652 char drxDapDRXJVersionText[] = "0.0.0";
653
654 DRXVersion_t drxDapDRXJVersion = {
655 DRX_MODULE_DAP, /**< type identifier of the module */
656 drxDapDRXJModuleName, /**< name or description of module */
657
658 0, /**< major version number */
659 0, /**< minor version number */
660 0, /**< patch version number */
661 drxDapDRXJVersionText /**< version as text string */
662 };
663
664 /* The structure containing the protocol interface */
665 DRXAccessFunc_t drxDapDRXJFunct_g = {
666 &drxDapDRXJVersion,
667 DRXJ_DAP_WriteBlock, /* Supported */
668 DRXJ_DAP_ReadBlock, /* Supported */
669 DRXJ_DAP_WriteReg8, /* Not supported */
670 DRXJ_DAP_ReadReg8, /* Not supported */
671 DRXJ_DAP_ReadModifyWriteReg8, /* Not supported */
672 DRXJ_DAP_WriteReg16, /* Supported */
673 DRXJ_DAP_ReadReg16, /* Supported */
674 DRXJ_DAP_ReadModifyWriteReg16, /* Supported */
675 DRXJ_DAP_WriteReg32, /* Supported */
676 DRXJ_DAP_ReadReg32, /* Supported */
677 DRXJ_DAP_ReadModifyWriteReg32, /* Not supported */
678 };
679
680 /**
681 * /var DRXJ_Func_g
682 * /brief The driver functions of the drxj
683 */
684 DRXDemodFunc_t DRXJFunctions_g = {
685 DRXJ_TYPE_ID,
686 DRXJ_Open,
687 DRXJ_Close,
688 DRXJ_Ctrl
689 };
690
691 DRXJData_t DRXJData_g = {
692 FALSE, /* hasLNA : TRUE if LNA (aka PGA) present */
693 FALSE, /* hasOOB : TRUE if OOB supported */
694 FALSE, /* hasNTSC: TRUE if NTSC supported */
695 FALSE, /* hasBTSC: TRUE if BTSC supported */
696 FALSE, /* hasSMATX: TRUE if SMA_TX pin is available */
697 FALSE, /* hasSMARX: TRUE if SMA_RX pin is available */
698 FALSE, /* hasGPIO : TRUE if GPIO pin is available */
699 FALSE, /* hasIRQN : TRUE if IRQN pin is available */
700 0, /* mfx A1/A2/A... */
701
702 /* tuner settings */
703 FALSE, /* tuner mirrors RF signal */
704 /* standard/channel settings */
705 DRX_STANDARD_UNKNOWN, /* current standard */
706 DRX_CONSTELLATION_AUTO, /* constellation */
707 0, /* frequency in KHz */
708 DRX_BANDWIDTH_UNKNOWN, /* currBandwidth */
709 DRX_MIRROR_NO, /* mirror */
710
711 /* signal quality information: */
712 /* default values taken from the QAM Programming guide */
713 /* fecBitsDesired should not be less than 4000000 */
714 4000000, /* fecBitsDesired */
715 5, /* fecVdPlen */
716 4, /* qamVdPrescale */
717 0xFFFF, /* qamVDPeriod */
718 204 * 8, /* fecRsPlen annex A */
719 1, /* fecRsPrescale */
720 FEC_RS_MEASUREMENT_PERIOD, /* fecRsPeriod */
721 TRUE, /* resetPktErrAcc */
722 0, /* pktErrAccStart */
723
724 /* HI configuration */
725 0, /* HICfgTimingDiv */
726 0, /* HICfgBridgeDelay */
727 0, /* HICfgWakeUpKey */
728 0, /* HICfgCtrl */
729 0, /* HICfgTimeout */
730 /* UIO configuartion */
731 DRX_UIO_MODE_DISABLE, /* uioSmaRxMode */
732 DRX_UIO_MODE_DISABLE, /* uioSmaTxMode */
733 DRX_UIO_MODE_DISABLE, /* uioASELMode */
734 DRX_UIO_MODE_DISABLE, /* uioIRQNMode */
735 /* FS setting */
736 0UL, /* iqmFsRateOfs */
737 FALSE, /* posImage */
738 /* RC setting */
739 0UL, /* iqmRcRateOfs */
740 /* AUD information */
741 /* FALSE, * flagSetAUDdone */
742 /* FALSE, * detectedRDS */
743 /* TRUE, * flagASDRequest */
744 /* FALSE, * flagHDevClear */
745 /* FALSE, * flagHDevSet */
746 /* (u16_t) 0xFFF, * rdsLastCount */
747
748 /*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
749 FALSE, * flagAudMcUploaded */
750 /*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
751 /* ATV configuartion */
752 0UL, /* flags cfg changes */
753 /* shadow of ATV_TOP_EQU0__A */
754 {-5,
755 ATV_TOP_EQU0_EQU_C0_FM,
756 ATV_TOP_EQU0_EQU_C0_L,
757 ATV_TOP_EQU0_EQU_C0_LP,
758 ATV_TOP_EQU0_EQU_C0_BG,
759 ATV_TOP_EQU0_EQU_C0_DK,
760 ATV_TOP_EQU0_EQU_C0_I},
761 /* shadow of ATV_TOP_EQU1__A */
762 {-50,
763 ATV_TOP_EQU1_EQU_C1_FM,
764 ATV_TOP_EQU1_EQU_C1_L,
765 ATV_TOP_EQU1_EQU_C1_LP,
766 ATV_TOP_EQU1_EQU_C1_BG,
767 ATV_TOP_EQU1_EQU_C1_DK,
768 ATV_TOP_EQU1_EQU_C1_I},
769 /* shadow of ATV_TOP_EQU2__A */
770 {210,
771 ATV_TOP_EQU2_EQU_C2_FM,
772 ATV_TOP_EQU2_EQU_C2_L,
773 ATV_TOP_EQU2_EQU_C2_LP,
774 ATV_TOP_EQU2_EQU_C2_BG,
775 ATV_TOP_EQU2_EQU_C2_DK,
776 ATV_TOP_EQU2_EQU_C2_I},
777 /* shadow of ATV_TOP_EQU3__A */
778 {-160,
779 ATV_TOP_EQU3_EQU_C3_FM,
780 ATV_TOP_EQU3_EQU_C3_L,
781 ATV_TOP_EQU3_EQU_C3_LP,
782 ATV_TOP_EQU3_EQU_C3_BG,
783 ATV_TOP_EQU3_EQU_C3_DK,
784 ATV_TOP_EQU3_EQU_C3_I},
785 FALSE, /* flag: TRUE=bypass */
786 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
787 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
788 TRUE, /* flag CVBS ouput enable */
789 FALSE, /* flag SIF ouput enable */
790 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
791 { /* qamRfAgcCfg */
792 DRX_STANDARD_ITU_B, /* standard */
793 DRX_AGC_CTRL_AUTO, /* ctrlMode */
794 0, /* outputLevel */
795 0, /* minOutputLevel */
796 0xFFFF, /* maxOutputLevel */
797 0x0000, /* speed */
798 0x0000, /* top */
799 0x0000 /* c.o.c. */
800 },
801 { /* qamIfAgcCfg */
802 DRX_STANDARD_ITU_B, /* standard */
803 DRX_AGC_CTRL_AUTO, /* ctrlMode */
804 0, /* outputLevel */
805 0, /* minOutputLevel */
806 0xFFFF, /* maxOutputLevel */
807 0x0000, /* speed */
808 0x0000, /* top (don't care) */
809 0x0000 /* c.o.c. (don't care) */
810 },
811 { /* vsbRfAgcCfg */
812 DRX_STANDARD_8VSB, /* standard */
813 DRX_AGC_CTRL_AUTO, /* ctrlMode */
814 0, /* outputLevel */
815 0, /* minOutputLevel */
816 0xFFFF, /* maxOutputLevel */
817 0x0000, /* speed */
818 0x0000, /* top (don't care) */
819 0x0000 /* c.o.c. (don't care) */
820 },
821 { /* vsbIfAgcCfg */
822 DRX_STANDARD_8VSB, /* standard */
823 DRX_AGC_CTRL_AUTO, /* ctrlMode */
824 0, /* outputLevel */
825 0, /* minOutputLevel */
826 0xFFFF, /* maxOutputLevel */
827 0x0000, /* speed */
828 0x0000, /* top (don't care) */
829 0x0000 /* c.o.c. (don't care) */
830 },
831 0, /* qamPgaCfg */
832 0, /* vsbPgaCfg */
833 { /* qamPreSawCfg */
834 DRX_STANDARD_ITU_B, /* standard */
835 0, /* reference */
836 FALSE /* usePreSaw */
837 },
838 { /* vsbPreSawCfg */
839 DRX_STANDARD_8VSB, /* standard */
840 0, /* reference */
841 FALSE /* usePreSaw */
842 },
843
844 /* Version information */
845 #ifndef _CH_
846 {
847 "01234567890", /* human readable version microcode */
848 "01234567890" /* human readable version device specific code */
849 },
850 {
851 { /* DRXVersion_t for microcode */
852 DRX_MODULE_UNKNOWN,
853 (char *)(NULL),
854 0,
855 0,
856 0,
857 (char *)(NULL)
858 },
859 { /* DRXVersion_t for device specific code */
860 DRX_MODULE_UNKNOWN,
861 (char *)(NULL),
862 0,
863 0,
864 0,
865 (char *)(NULL)
866 }
867 },
868 {
869 { /* DRXVersionList_t for microcode */
870 (pDRXVersion_t) (NULL),
871 (pDRXVersionList_t) (NULL)
872 },
873 { /* DRXVersionList_t for device specific code */
874 (pDRXVersion_t) (NULL),
875 (pDRXVersionList_t) (NULL)
876 }
877 },
878 #endif
879 FALSE, /* smartAntInverted */
880 /* Tracking filter setting for OOB */
881 {
882 12000,
883 9300,
884 6600,
885 5280,
886 3700,
887 3000,
888 2000,
889 0},
890 FALSE, /* oobPowerOn */
891 0, /* mpegTsStaticBitrate */
892 FALSE, /* disableTEIhandling */
893 FALSE, /* bitReverseMpegOutout */
894 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpegOutputClockRate */
895 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpegStartWidth */
896
897 /* Pre SAW & Agc configuration for ATV */
898 {
899 DRX_STANDARD_NTSC, /* standard */
900 7, /* reference */
901 TRUE /* usePreSaw */
902 },
903 { /* ATV RF-AGC */
904 DRX_STANDARD_NTSC, /* standard */
905 DRX_AGC_CTRL_AUTO, /* ctrlMode */
906 0, /* outputLevel */
907 0, /* minOutputLevel (d.c.) */
908 0, /* maxOutputLevel (d.c.) */
909 3, /* speed */
910 9500, /* top */
911 4000 /* cut-off current */
912 },
913 { /* ATV IF-AGC */
914 DRX_STANDARD_NTSC, /* standard */
915 DRX_AGC_CTRL_AUTO, /* ctrlMode */
916 0, /* outputLevel */
917 0, /* minOutputLevel (d.c.) */
918 0, /* maxOutputLevel (d.c.) */
919 3, /* speed */
920 2400, /* top */
921 0 /* c.o.c. (d.c.) */
922 },
923 140, /* ATV PGA config */
924 0, /* currSymbolRate */
925
926 FALSE, /* pdrSafeMode */
927 SIO_PDR_GPIO_CFG__PRE, /* pdrSafeRestoreValGpio */
928 SIO_PDR_VSYNC_CFG__PRE, /* pdrSafeRestoreValVSync */
929 SIO_PDR_SMA_RX_CFG__PRE, /* pdrSafeRestoreValSmaRx */
930 SIO_PDR_SMA_TX_CFG__PRE, /* pdrSafeRestoreValSmaTx */
931
932 4, /* oobPreSaw */
933 DRXJ_OOB_LO_POW_MINUS10DB, /* oobLoPow */
934 {
935 FALSE /* audData, only first member */
936 },
937 };
938
939 /**
940 * \var DRXJDefaultAddr_g
941 * \brief Default I2C address and device identifier.
942 */
943 I2CDeviceAddr_t DRXJDefaultAddr_g = {
944 DRXJ_DEF_I2C_ADDR, /* i2c address */
945 DRXJ_DEF_DEMOD_DEV_ID /* device id */
946 };
947
948 /**
949 * \var DRXJDefaultCommAttr_g
950 * \brief Default common attributes of a drxj demodulator instance.
951 */
952 DRXCommonAttr_t DRXJDefaultCommAttr_g = {
953 (pu8_t) NULL, /* ucode ptr */
954 0, /* ucode size */
955 TRUE, /* ucode verify switch */
956 {0}, /* version record */
957
958 44000, /* IF in kHz in case no tuner instance is used */
959 (151875 - 0), /* system clock frequency in kHz */
960 0, /* oscillator frequency kHz */
961 0, /* oscillator deviation in ppm, signed */
962 FALSE, /* If TRUE mirror frequency spectrum */
963 {
964 /* MPEG output configuration */
965 TRUE, /* If TRUE, enable MPEG ouput */
966 FALSE, /* If TRUE, insert RS byte */
967 TRUE, /* If TRUE, parallel out otherwise serial */
968 FALSE, /* If TRUE, invert DATA signals */
969 FALSE, /* If TRUE, invert ERR signal */
970 FALSE, /* If TRUE, invert STR signals */
971 FALSE, /* If TRUE, invert VAL signals */
972 FALSE, /* If TRUE, invert CLK signals */
973 TRUE, /* If TRUE, static MPEG clockrate will
974 be used, otherwise clockrate will
975 adapt to the bitrate of the TS */
976 19392658UL, /* Maximum bitrate in b/s in case
977 static clockrate is selected */
978 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
979 },
980 /* Initilisations below can be ommited, they require no user input and
981 are initialy 0, NULL or FALSE. The compiler will initialize them to these
982 values when ommited. */
983 FALSE, /* isOpened */
984
985 /* SCAN */
986 NULL, /* no scan params yet */
987 0, /* current scan index */
988 0, /* next scan frequency */
989 FALSE, /* scan ready flag */
990 0, /* max channels to scan */
991 0, /* nr of channels scanned */
992 NULL, /* default scan function */
993 NULL, /* default context pointer */
994 0, /* millisec to wait for demod lock */
995 DRXJ_DEMOD_LOCK, /* desired lock */
996 FALSE,
997
998 /* Power management */
999 DRX_POWER_UP,
1000
1001 /* Tuner */
1002 1, /* nr of I2C port to wich tuner is */
1003 0L, /* minimum RF input frequency, in kHz */
1004 0L, /* maximum RF input frequency, in kHz */
1005 FALSE, /* Rf Agc Polarity */
1006 FALSE, /* If Agc Polarity */
1007 FALSE, /* tuner slow mode */
1008
1009 { /* current channel (all 0) */
1010 0UL /* channel.frequency */
1011 },
1012 DRX_STANDARD_UNKNOWN, /* current standard */
1013 DRX_STANDARD_UNKNOWN, /* previous standard */
1014 DRX_STANDARD_UNKNOWN, /* diCacheStandard */
1015 FALSE, /* useBootloader */
1016 0UL, /* capabilities */
1017 0 /* mfx */
1018 };
1019
1020 /**
1021 * \var DRXJDefaultDemod_g
1022 * \brief Default drxj demodulator instance.
1023 */
1024 DRXDemodInstance_t DRXJDefaultDemod_g = {
1025 &DRXJFunctions_g, /* demod functions */
1026 &DRXJ_DAP, /* data access protocol functions */
1027 NULL, /* tuner instance */
1028 &DRXJDefaultAddr_g, /* i2c address & device id */
1029 &DRXJDefaultCommAttr_g, /* demod common attributes */
1030 &DRXJData_g /* demod device specific attributes */
1031 };
1032
1033 /**
1034 * \brief Default audio data structure for DRK demodulator instance.
1035 *
1036 * This structure is DRXK specific.
1037 *
1038 */
1039 DRXAudData_t DRXJDefaultAudData_g = {
1040 FALSE, /* audioIsActive */
1041 DRX_AUD_STANDARD_AUTO, /* audioStandard */
1042
1043 /* i2sdata */
1044 {
1045 FALSE, /* outputEnable */
1046 48000, /* frequency */
1047 DRX_I2S_MODE_MASTER, /* mode */
1048 DRX_I2S_WORDLENGTH_32, /* wordLength */
1049 DRX_I2S_POLARITY_RIGHT, /* polarity */
1050 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
1051 },
1052 /* volume */
1053 {
1054 TRUE, /* mute; */
1055 0, /* volume */
1056 DRX_AUD_AVC_OFF, /* avcMode */
1057 0, /* avcRefLevel */
1058 DRX_AUD_AVC_MAX_GAIN_12DB, /* avcMaxGain */
1059 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avcMaxAtten */
1060 0, /* strengthLeft */
1061 0 /* strengthRight */
1062 },
1063 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* autoSound */
1064 /* assThresholds */
1065 {
1066 440, /* A2 */
1067 12, /* BTSC */
1068 700, /* NICAM */
1069 },
1070 /* carrier */
1071 {
1072 /* a */
1073 {
1074 42, /* thres */
1075 DRX_NO_CARRIER_NOISE, /* opt */
1076 0, /* shift */
1077 0 /* dco */
1078 },
1079 /* b */
1080 {
1081 42, /* thres */
1082 DRX_NO_CARRIER_MUTE, /* opt */
1083 0, /* shift */
1084 0 /* dco */
1085 },
1086
1087 },
1088 /* mixer */
1089 {
1090 DRX_AUD_SRC_STEREO_OR_A, /* sourceI2S */
1091 DRX_AUD_I2S_MATRIX_STEREO, /* matrixI2S */
1092 DRX_AUD_FM_MATRIX_SOUND_A /* matrixFm */
1093 },
1094 DRX_AUD_DEVIATION_NORMAL, /* deviation */
1095 DRX_AUD_AVSYNC_OFF, /* avSync */
1096
1097 /* prescale */
1098 {
1099 DRX_AUD_MAX_FM_DEVIATION, /* fmDeviation */
1100 DRX_AUD_MAX_NICAM_PRESCALE /* nicamGain */
1101 },
1102 DRX_AUD_FM_DEEMPH_75US, /* deemph */
1103 DRX_BTSC_STEREO, /* btscDetect */
1104 0, /* rdsDataCounter */
1105 FALSE /* rdsDataPresent */
1106 };
1107
1108 /*-----------------------------------------------------------------------------
1109 STRUCTURES
1110 ----------------------------------------------------------------------------*/
1111 typedef struct {
1112 u16_t eqMSE;
1113 u8_t eqMode;
1114 u8_t eqCtrl;
1115 u8_t eqStat;
1116 } DRXJEQStat_t, *pDRXJEQStat_t;
1117
1118 /* HI command */
1119 typedef struct {
1120 u16_t cmd;
1121 u16_t param1;
1122 u16_t param2;
1123 u16_t param3;
1124 u16_t param4;
1125 u16_t param5;
1126 u16_t param6;
1127 } DRXJHiCmd_t, *pDRXJHiCmd_t;
1128
1129 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1130 /*============================================================================*/
1131 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1132 /*============================================================================*/
1133
1134 typedef struct {
1135 u32_t addr;
1136 u16_t size;
1137 u16_t flags; /* bit[15..2]=reserved,
1138 bit[1]= compression on/off
1139 bit[0]= CRC on/off */
1140 u16_t CRC;
1141 } DRXUCodeBlockHdr_t, *pDRXUCodeBlockHdr_t;
1142 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1143
1144 /*-----------------------------------------------------------------------------
1145 FUNCTIONS
1146 ----------------------------------------------------------------------------*/
1147 /* Some prototypes */
1148 static DRXStatus_t
1149 HICommand(const pI2CDeviceAddr_t devAddr,
1150 const pDRXJHiCmd_t cmd, pu16_t result);
1151
1152 static DRXStatus_t
1153 CtrlLockStatus(pDRXDemodInstance_t demod, pDRXLockStatus_t lockStat);
1154
1155 static DRXStatus_t
1156 CtrlPowerMode(pDRXDemodInstance_t demod, pDRXPowerMode_t mode);
1157
1158 static DRXStatus_t PowerDownAud(pDRXDemodInstance_t demod);
1159
1160 #ifndef DRXJ_DIGITAL_ONLY
1161 static DRXStatus_t PowerUpAud(pDRXDemodInstance_t demod, Bool_t setStandard);
1162 #endif
1163
1164 static DRXStatus_t
1165 AUDCtrlSetStandard(pDRXDemodInstance_t demod, pDRXAudStandard_t standard);
1166
1167 static DRXStatus_t
1168 CtrlSetCfgPreSaw(pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw);
1169
1170 static DRXStatus_t
1171 CtrlSetCfgAfeGain(pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain);
1172
1173 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1174 static DRXStatus_t
1175 CtrlUCodeUpload(pDRXDemodInstance_t demod,
1176 pDRXUCodeInfo_t mcInfo,
1177 DRXUCodeAction_t action, Bool_t audioMCUpload);
1178 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1179
1180 /*============================================================================*/
1181 /*============================================================================*/
1182 /*== HELPER FUNCTIONS ==*/
1183 /*============================================================================*/
1184 /*============================================================================*/
1185
1186 /**
1187 * \fn void Mult32(u32_t a, u32_t b, pu32_t h, pu32_t l)
1188 * \brief 32bitsx32bits signed multiplication
1189 * \param a 32 bits multiplicant, typecast from signed to unisgned
1190 * \param b 32 bits multiplier, typecast from signed to unisgned
1191 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1192 * \param l pointer to low part 64 bits result
1193 *
1194 * For the 2n+n addition a + b:
1195 * if a >= 0, then h += 0 (sign extension = 0)
1196 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1197 *
1198 * Also, if a + b < 2^n, then a + b >= a && a + b >= b
1199 * but if a + b >= 2^n, then R = a + b - 2^n,
1200 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1201 * Therefore, to detect overflow, simply compare the addition result with
1202 * one of the operands; if the result is smaller, overflow has occurred and
1203 * h must be incremented.
1204 *
1205 * Booth multiplication uses additions and subtractions to reduce the number
1206 * of iterations. This is done by taking three subsequent bits abc and calculating
1207 * the following multiplication factor: -2a + b + c. This factor is multiplied
1208 * by the second operand and added to the result. Next, the first operand is
1209 * shifted two bits (hence one of the three bits is reused) and the process
1210 * repeated. The last iteration has only two bits left, but we simply add
1211 * a zero to the end.
1212 *
1213 * Hence: (n=4)
1214 * 1 * a = 0 * 4a + 1 * a
1215 * 2 * a = 1 * 4a - 2 * a
1216 * 3 * a = 1 * 4a - 1 * a
1217 * -1 * a = 0 * 4a - 1 * a
1218 * -5 * a = -1 * 4a - 1 * a
1219 *
1220 * etc.
1221 *
1222 * Note that the function is type size independent. Any unsigned integer type
1223 * can be substituted for booth_t.
1224 *
1225 */
1226
1227 #define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof (u32_t) * 8 - 1))) != 0)
1228
1229 static void Mult32(u32_t a, u32_t b, pu32_t h, pu32_t l)
1230 {
1231 unsigned int i;
1232 *h = *l = 0;
1233
1234 /* n/2 iterations; shift operand a left two bits after each iteration. */
1235 /* This automatically appends a zero to the operand for the last iteration. */
1236 for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1237 /* Shift result left two bits */
1238 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1239 *l = (*l << 2);
1240
1241 /* Take the first three bits of operand a for the Booth conversion: */
1242 /* 0, 7: do nothing */
1243 /* 1, 2: add b */
1244 /* 3 : add 2b */
1245 /* 4 : subtract 2b */
1246 /* 5, 6: subtract b */
1247 switch (a >> (sizeof(a) * 8 - 3)) {
1248 case 3:
1249 *l += b;
1250 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1251 case 1:
1252 case 2:
1253 *l += b;
1254 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1255 break;
1256 case 4:
1257 *l -= b;
1258 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1259 ((u32_t)
1260 (-
1261 ((s32_t)
1262 b))));
1263 case 5:
1264 case 6:
1265 *l -= b;
1266 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1267 ((u32_t)
1268 (-
1269 ((s32_t)
1270 b))));
1271 break;
1272 }
1273 }
1274 }
1275
1276 /*============================================================================*/
1277
1278 /*
1279 * \fn u32_t Frac28(u32_t N, u32_t D)
1280 * \brief Compute: (1<<28)*N/D
1281 * \param N 32 bits
1282 * \param D 32 bits
1283 * \return (1<<28)*N/D
1284 * This function is used to avoid floating-point calculations as they may
1285 * not be present on the target platform.
1286
1287 * Frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1288 * fraction used for setting the Frequency Shifter registers.
1289 * N and D can hold numbers up to width: 28-bits.
1290 * The 4 bits integer part and the 28 bits fractional part are calculated.
1291
1292 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1293
1294 * N: 0...(1<<28)-1 = 268435454
1295 * D: 0...(1<<28)-1
1296 * Q: 0...(1<<32)-1
1297 */
1298 static u32_t Frac28(u32_t N, u32_t D)
1299 {
1300 int i = 0;
1301 u32_t Q1 = 0;
1302 u32_t R0 = 0;
1303
1304 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1305 Q1 = N / D; /* integer part, only the 4 least significant bits
1306 will be visible in the result */
1307
1308 /* division using radix 16, 7 nibbles in the result */
1309 for (i = 0; i < 7; i++) {
1310 Q1 = (Q1 << 4) | R0 / D;
1311 R0 = (R0 % D) << 4;
1312 }
1313 /* rounding */
1314 if ((R0 >> 3) >= D)
1315 Q1++;
1316
1317 return Q1;
1318 }
1319
1320 /**
1321 * \fn u32_t Log10Times100( u32_t x)
1322 * \brief Compute: 100*log10(x)
1323 * \param x 32 bits
1324 * \return 100*log10(x)
1325 *
1326 * 100*log10(x)
1327 * = 100*(log2(x)/log2(10)))
1328 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1329 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1330 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1331 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1332 *
1333 * where y = 2^k and 1<= (x/y) < 2
1334 */
1335
1336 static u32_t Log10Times100(u32_t x)
1337 {
1338 static const u8_t scale = 15;
1339 static const u8_t indexWidth = 5;
1340 /*
1341 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1342 0 <= n < ((1<<INDEXWIDTH)+1)
1343 */
1344
1345 static const u32_t log2lut[] = {
1346 0, /* 0.000000 */
1347 290941, /* 290941.300628 */
1348 573196, /* 573196.476418 */
1349 847269, /* 847269.179851 */
1350 1113620, /* 1113620.489452 */
1351 1372674, /* 1372673.576986 */
1352 1624818, /* 1624817.752104 */
1353 1870412, /* 1870411.981536 */
1354 2109788, /* 2109787.962654 */
1355 2343253, /* 2343252.817465 */
1356 2571091, /* 2571091.461923 */
1357 2793569, /* 2793568.696416 */
1358 3010931, /* 3010931.055901 */
1359 3223408, /* 3223408.452106 */
1360 3431216, /* 3431215.635215 */
1361 3634553, /* 3634553.498355 */
1362 3833610, /* 3833610.244726 */
1363 4028562, /* 4028562.434393 */
1364 4219576, /* 4219575.925308 */
1365 4406807, /* 4406806.721144 */
1366 4590402, /* 4590401.736809 */
1367 4770499, /* 4770499.491025 */
1368 4947231, /* 4947230.734179 */
1369 5120719, /* 5120719.018555 */
1370 5291081, /* 5291081.217197 */
1371 5458428, /* 5458427.996830 */
1372 5622864, /* 5622864.249668 */
1373 5784489, /* 5784489.488298 */
1374 5943398, /* 5943398.207380 */
1375 6099680, /* 6099680.215452 */
1376 6253421, /* 6253420.939751 */
1377 6404702, /* 6404701.706649 */
1378 6553600, /* 6553600.000000 */
1379 };
1380
1381 u8_t i = 0;
1382 u32_t y = 0;
1383 u32_t d = 0;
1384 u32_t k = 0;
1385 u32_t r = 0;
1386
1387 if (x == 0)
1388 return (0);
1389
1390 /* Scale x (normalize) */
1391 /* computing y in log(x/y) = log(x) - log(y) */
1392 if ((x & (((u32_t) (-1)) << (scale + 1))) == 0) {
1393 for (k = scale; k > 0; k--) {
1394 if (x & (((u32_t) 1) << scale))
1395 break;
1396 x <<= 1;
1397 }
1398 } else {
1399 for (k = scale; k < 31; k++) {
1400 if ((x & (((u32_t) (-1)) << (scale + 1))) == 0)
1401 break;
1402 x >>= 1;
1403 }
1404 }
1405 /*
1406 Now x has binary point between bit[scale] and bit[scale-1]
1407 and 1.0 <= x < 2.0 */
1408
1409 /* correction for divison: log(x) = log(x/y)+log(y) */
1410 y = k * ((((u32_t) 1) << scale) * 200);
1411
1412 /* remove integer part */
1413 x &= ((((u32_t) 1) << scale) - 1);
1414 /* get index */
1415 i = (u8_t) (x >> (scale - indexWidth));
1416 /* compute delta (x-a) */
1417 d = x & ((((u32_t) 1) << (scale - indexWidth)) - 1);
1418 /* compute log, multiplication ( d* (.. )) must be within range ! */
1419 y += log2lut[i] +
1420 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
1421 /* Conver to log10() */
1422 y /= 108853; /* (log2(10) << scale) */
1423 r = (y >> 1);
1424 /* rounding */
1425 if (y & ((u32_t) 1))
1426 r++;
1427
1428 return (r);
1429
1430 }
1431
1432 /**
1433 * \fn u32_t FracTimes1e6( u16_t N, u32_t D)
1434 * \brief Compute: (N/D) * 1000000.
1435 * \param N nominator 16-bits.
1436 * \param D denominator 32-bits.
1437 * \return u32_t
1438 * \retval ((N/D) * 1000000), 32 bits
1439 *
1440 * No check on D=0!
1441 */
1442 static u32_t FracTimes1e6(u32_t N, u32_t D)
1443 {
1444 u32_t remainder = 0;
1445 u32_t frac = 0;
1446
1447 /*
1448 frac = (N * 1000000) / D
1449 To let it fit in a 32 bits computation:
1450 frac = (N * (1000000 >> 4)) / (D >> 4)
1451 This would result in a problem in case D < 16 (div by 0).
1452 So we do it more elaborate as shown below.
1453 */
1454 frac = (((u32_t) N) * (1000000 >> 4)) / D;
1455 frac <<= 4;
1456 remainder = (((u32_t) N) * (1000000 >> 4)) % D;
1457 remainder <<= 4;
1458 frac += remainder / D;
1459 remainder = remainder % D;
1460 if ((remainder * 2) > D) {
1461 frac++;
1462 }
1463
1464 return (frac);
1465 }
1466
1467 /*============================================================================*/
1468
1469 /**
1470 * \brief Compute: 100 * 10^( GdB / 200 ).
1471 * \param u32_t GdB Gain in 0.1dB
1472 * \return u32_t Gainfactor in 0.01 resolution
1473 *
1474 */
1475 static u32_t dB2LinTimes100(u32_t GdB)
1476 {
1477 u32_t result = 0;
1478 u32_t nr6dBSteps = 0;
1479 u32_t remainder = 0;
1480 u32_t remainderFac = 0;
1481
1482 /* start with factors 2 (6.02dB) */
1483 nr6dBSteps = GdB * 1000UL / 60206UL;
1484 if (nr6dBSteps > 17) {
1485 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1486 return MAX_U32;
1487 }
1488 result = (1 << nr6dBSteps);
1489
1490 /* calculate remaining factor,
1491 poly approximation of 10^(GdB/200):
1492
1493 y = 1E-04x2 + 0.0106x + 1.0026
1494
1495 max deviation < 0.005 for range x = [0 ... 60]
1496 */
1497 remainder = ((GdB * 1000UL) % 60206UL) / 1000UL;
1498 /* using 1e-4 for poly calculation */
1499 remainderFac = 1 * remainder * remainder;
1500 remainderFac += 106 * remainder;
1501 remainderFac += 10026;
1502
1503 /* multiply by remaining factor */
1504 result *= remainderFac;
1505
1506 /* conversion from 1e-4 to 1e-2 */
1507 return ((result + 50) / 100);
1508 }
1509
1510 #ifndef DRXJ_DIGITAL_ONLY
1511 #define FRAC_FLOOR 0
1512 #define FRAC_CEIL 1
1513 #define FRAC_ROUND 2
1514 /**
1515 * \fn u32_t Frac( u32_t N, u32_t D, u16_t RC )
1516 * \brief Compute: N/D.
1517 * \param N nominator 32-bits.
1518 * \param D denominator 32-bits.
1519 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1520 * \return u32_t
1521 * \retval N/D, 32 bits
1522 *
1523 * If D=0 returns 0
1524 */
1525 static u32_t Frac(u32_t N, u32_t D, u16_t RC)
1526 {
1527 u32_t remainder = 0;
1528 u32_t frac = 0;
1529 u16_t bitCnt = 32;
1530
1531 if (D == 0) {
1532 frac = 0;
1533 remainder = 0;
1534
1535 return (frac);
1536 }
1537
1538 if (D > N) {
1539 frac = 0;
1540 remainder = N;
1541 } else {
1542 remainder = 0;
1543 frac = N;
1544 while (bitCnt-- > 0) {
1545 remainder <<= 1;
1546 remainder |= ((frac & 0x80000000) >> 31);
1547 frac <<= 1;
1548 if (remainder < D) {
1549 frac &= 0xFFFFFFFE;
1550 } else {
1551 remainder -= D;
1552 frac |= 0x1;
1553 }
1554 }
1555
1556 /* result correction if needed */
1557 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1558 /* ceil the result */
1559 /*(remainder is not zero -> value behind decimal point exists) */
1560 frac++;
1561 }
1562 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1563 /* remainder is bigger from D/2 -> round the result */
1564 frac++;
1565 }
1566 }
1567
1568 return (frac);
1569 }
1570 #endif
1571
1572 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1573 /*============================================================================*/
1574
1575 /**
1576 * \fn u16_t UCodeRead16( pu8_t addr)
1577 * \brief Read a 16 bits word, expect big endian data.
1578 * \return u16_t The data read.
1579 */
1580 static u16_t UCodeRead16(pu8_t addr)
1581 {
1582 /* Works fo any host processor */
1583
1584 u16_t word = 0;
1585
1586 word = ((u16_t) addr[0]);
1587 word <<= 8;
1588 word |= ((u16_t) addr[1]);
1589
1590 return (word);
1591 }
1592
1593 /*============================================================================*/
1594
1595 /**
1596 * \fn u32_t UCodeRead32( pu8_t addr)
1597 * \brief Read a 32 bits word, expect big endian data.
1598 * \return u32_t The data read.
1599 */
1600 static u32_t UCodeRead32(pu8_t addr)
1601 {
1602 /* Works fo any host processor */
1603
1604 u32_t word = 0;
1605
1606 word = ((u16_t) addr[0]);
1607 word <<= 8;
1608 word |= ((u16_t) addr[1]);
1609 word <<= 8;
1610 word |= ((u16_t) addr[2]);
1611 word <<= 8;
1612 word |= ((u16_t) addr[3]);
1613
1614 return (word);
1615 }
1616
1617 /*============================================================================*/
1618
1619 /**
1620 * \fn u16_t UCodeComputeCRC (pu8_t blockData, u16_t nrWords)
1621 * \brief Compute CRC of block of microcode data.
1622 * \param blockData Pointer to microcode data.
1623 * \param nrWords Size of microcode block (number of 16 bits words).
1624 * \return u16_t The computed CRC residu.
1625 */
1626 static u16_t UCodeComputeCRC(pu8_t blockData, u16_t nrWords)
1627 {
1628 u16_t i = 0;
1629 u16_t j = 0;
1630 u32_t CRCWord = 0;
1631 u32_t carry = 0;
1632
1633 while (i < nrWords) {
1634 CRCWord |= (u32_t) UCodeRead16(blockData);
1635 for (j = 0; j < 16; j++) {
1636 CRCWord <<= 1;
1637 if (carry != 0)
1638 CRCWord ^= 0x80050000UL;
1639 carry = CRCWord & 0x80000000UL;
1640 }
1641 i++;
1642 blockData += (sizeof(u16_t));
1643 }
1644 return ((u16_t) (CRCWord >> 16));
1645 }
1646 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1647
1648 /**
1649 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1650 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1651 *
1652 */
1653 static const u16_t NicamPrescTableVal[43] =
1654 { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1655 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1656 18, 20, 23, 25, 28, 32, 36, 40, 45,
1657 51, 57, 64, 71, 80, 90, 101, 113, 127
1658 };
1659
1660 /*============================================================================*/
1661 /*== END HELPER FUNCTIONS ==*/
1662 /*============================================================================*/
1663
1664 /*============================================================================*/
1665 /*============================================================================*/
1666 /*== DRXJ DAP FUNCTIONS ==*/
1667 /*============================================================================*/
1668 /*============================================================================*/
1669
1670 /*
1671 This layer takes care of some device specific register access protocols:
1672 -conversion to short address format
1673 -access to audio block
1674 This layer is placed between the drx_dap_fasi and the rest of the drxj
1675 specific implementation. This layer can use address map knowledge whereas
1676 dap_fasi may not use memory map knowledge.
1677
1678 * For audio currently only 16 bits read and write register access is
1679 supported. More is not needed. RMW and 32 or 8 bit access on audio
1680 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1681 single/multi master) will be ignored.
1682
1683 TODO: check ignoring single/multimaster is ok for AUD access ?
1684 */
1685
1686 #define DRXJ_ISAUDWRITE( addr ) (((((addr)>>16)&1)==1)?TRUE:FALSE)
1687 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1688 /*============================================================================*/
1689
1690 /**
1691 * \fn Bool_t IsHandledByAudTrIf( DRXaddr_t addr )
1692 * \brief Check if this address is handled by the audio token ring interface.
1693 * \param addr
1694 * \return Bool_t
1695 * \retval TRUE Yes, handled by audio token ring interface
1696 * \retval FALSE No, not handled by audio token ring interface
1697 *
1698 */
1699 static
1700 Bool_t IsHandledByAudTrIf(DRXaddr_t addr)
1701 {
1702 Bool_t retval = FALSE;
1703
1704 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1705 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1706 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1707 retval = TRUE;
1708 }
1709
1710 return (retval);
1711 }
1712
1713 /*============================================================================*/
1714
1715 static DRXStatus_t DRXJ_DAP_ReadBlock(pI2CDeviceAddr_t devAddr,
1716 DRXaddr_t addr,
1717 u16_t datasize,
1718 pu8_t data, DRXflags_t flags)
1719 {
1720 return drxDapFASIFunct_g.readBlockFunc(devAddr,
1721 addr, datasize, data, flags);
1722 }
1723
1724 /*============================================================================*/
1725
1726 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg8(pI2CDeviceAddr_t devAddr,
1727 DRXaddr_t waddr,
1728 DRXaddr_t raddr,
1729 u8_t wdata, pu8_t rdata)
1730 {
1731 return drxDapFASIFunct_g.readModifyWriteReg8Func(devAddr,
1732 waddr,
1733 raddr, wdata, rdata);
1734 }
1735
1736 /*============================================================================*/
1737
1738 /**
1739 * \fn DRXStatus_t DRXJ_DAP_RMWriteReg16Short
1740 * \brief Read modify write 16 bits audio register using short format only.
1741 * \param devAddr
1742 * \param waddr Address to write to
1743 * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1744 * \param wdata Data to write
1745 * \param rdata Buffer for data to read
1746 * \return DRXStatus_t
1747 * \retval DRX_STS_OK Succes
1748 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1749 *
1750 * 16 bits register read modify write access using short addressing format only.
1751 * Requires knowledge of the registermap, thus device dependent.
1752 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1753 *
1754 */
1755
1756 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1757 See comments DRXJ_DAP_ReadModifyWriteReg16 */
1758 #if ( DRXDAPFASI_LONG_ADDR_ALLOWED == 0 )
1759 static DRXStatus_t DRXJ_DAP_RMWriteReg16Short(pI2CDeviceAddr_t devAddr,
1760 DRXaddr_t waddr,
1761 DRXaddr_t raddr,
1762 u16_t wdata, pu16_t rdata)
1763 {
1764 DRXStatus_t rc;
1765
1766 if (rdata == NULL) {
1767 return DRX_STS_INVALID_ARG;
1768 }
1769
1770 /* Set RMW flag */
1771 rc = drxDapFASIFunct_g.writeReg16Func(devAddr,
1772 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1773 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1774 0x0000);
1775 if (rc == DRX_STS_OK) {
1776 /* Write new data: triggers RMW */
1777 rc = drxDapFASIFunct_g.writeReg16Func(devAddr, waddr, wdata,
1778 0x0000);
1779 }
1780 if (rc == DRX_STS_OK) {
1781 /* Read old data */
1782 rc = drxDapFASIFunct_g.readReg16Func(devAddr, raddr, rdata,
1783 0x0000);
1784 }
1785 if (rc == DRX_STS_OK) {
1786 /* Reset RMW flag */
1787 rc = drxDapFASIFunct_g.writeReg16Func(devAddr,
1788 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1789 0, 0x0000);
1790 }
1791
1792 return rc;
1793 }
1794 #endif
1795
1796 /*============================================================================*/
1797
1798 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg16(pI2CDeviceAddr_t devAddr,
1799 DRXaddr_t waddr,
1800 DRXaddr_t raddr,
1801 u16_t wdata, pu16_t rdata)
1802 {
1803 /* TODO: correct short/long addressing format decision,
1804 now long format has higher prio then short because short also
1805 needs virt bnks (not impl yet) for certain audio registers */
1806 #if ( DRXDAPFASI_LONG_ADDR_ALLOWED==1 )
1807 return drxDapFASIFunct_g.readModifyWriteReg16Func(devAddr,
1808 waddr,
1809 raddr, wdata, rdata);
1810 #else
1811 return DRXJ_DAP_RMWriteReg16Short(devAddr, waddr, raddr, wdata, rdata);
1812 #endif
1813 }
1814
1815 /*============================================================================*/
1816
1817 static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg32(pI2CDeviceAddr_t devAddr,
1818 DRXaddr_t waddr,
1819 DRXaddr_t raddr,
1820 u32_t wdata, pu32_t rdata)
1821 {
1822 return drxDapFASIFunct_g.readModifyWriteReg32Func(devAddr,
1823 waddr,
1824 raddr, wdata, rdata);
1825 }
1826
1827 /*============================================================================*/
1828
1829 static DRXStatus_t DRXJ_DAP_ReadReg8(pI2CDeviceAddr_t devAddr,
1830 DRXaddr_t addr,
1831 pu8_t data, DRXflags_t flags)
1832 {
1833 return drxDapFASIFunct_g.readReg8Func(devAddr, addr, data, flags);
1834 }
1835
1836 /*============================================================================*/
1837
1838 /**
1839 * \fn DRXStatus_t DRXJ_DAP_ReadAudReg16
1840 * \brief Read 16 bits audio register
1841 * \param devAddr
1842 * \param addr
1843 * \param data
1844 * \return DRXStatus_t
1845 * \retval DRX_STS_OK Succes
1846 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1847 *
1848 * 16 bits register read access via audio token ring interface.
1849 *
1850 */
1851 static DRXStatus_t DRXJ_DAP_ReadAudReg16(pI2CDeviceAddr_t devAddr,
1852 DRXaddr_t addr, pu16_t data)
1853 {
1854 u32_t startTimer = 0;
1855 u32_t currentTimer = 0;
1856 u32_t deltaTimer = 0;
1857 u16_t trStatus = 0;
1858 DRXStatus_t stat = DRX_STS_ERROR;
1859
1860 /* No read possible for bank 3, return with error */
1861 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1862 stat = DRX_STS_INVALID_ARG;
1863 } else {
1864 const DRXaddr_t writeBit = ((DRXaddr_t) 1) << 16;
1865
1866 /* Force reset write bit */
1867 addr &= (~writeBit);
1868
1869 /* Set up read */
1870 startTimer = DRXBSP_HST_Clock();
1871 do {
1872 /* RMW to aud TR IF until request is granted or timeout */
1873 stat = DRXJ_DAP_ReadModifyWriteReg16(devAddr,
1874 addr,
1875 SIO_HI_RA_RAM_S0_RMWBUF__A,
1876 0x0000, &trStatus);
1877
1878 if (stat != DRX_STS_OK) {
1879 break;
1880 };
1881
1882 currentTimer = DRXBSP_HST_Clock();
1883 deltaTimer = currentTimer - startTimer;
1884 if (deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1885 stat = DRX_STS_ERROR;
1886 break;
1887 };
1888
1889 } while (((trStatus & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1890 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1891 ((trStatus & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1892 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1893 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1894
1895 /* Wait for read ready status or timeout */
1896 if (stat == DRX_STS_OK) {
1897 startTimer = DRXBSP_HST_Clock();
1898
1899 while ((trStatus & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1900 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1901 stat = DRXJ_DAP_ReadReg16(devAddr,
1902 AUD_TOP_TR_CTR__A,
1903 &trStatus, 0x0000);
1904 if (stat != DRX_STS_OK) {
1905 break;
1906 };
1907
1908 currentTimer = DRXBSP_HST_Clock();
1909 deltaTimer = currentTimer - startTimer;
1910 if (deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1911 stat = DRX_STS_ERROR;
1912 break;
1913 };
1914 } /* while ( ... ) */
1915 }
1916
1917 /* if { stat == DRX_STS_OK ) */
1918 /* Read value */
1919 if (stat == DRX_STS_OK) {
1920 stat = DRXJ_DAP_ReadModifyWriteReg16(devAddr,
1921 AUD_TOP_TR_RD_REG__A,
1922 SIO_HI_RA_RAM_S0_RMWBUF__A,
1923 0x0000, data);
1924 }
1925 /* if { stat == DRX_STS_OK ) */
1926 return stat;
1927 }
1928
1929 /*============================================================================*/
1930
1931 static DRXStatus_t DRXJ_DAP_ReadReg16(pI2CDeviceAddr_t devAddr,
1932 DRXaddr_t addr,
1933 pu16_t data, DRXflags_t flags)
1934 {
1935 DRXStatus_t stat = DRX_STS_ERROR;
1936
1937 /* Check param */
1938 if ((devAddr == NULL) || (data == NULL)) {
1939 return DRX_STS_INVALID_ARG;
1940 }
1941
1942 if (IsHandledByAudTrIf(addr)) {
1943 stat = DRXJ_DAP_ReadAudReg16(devAddr, addr, data);
1944 } else {
1945 stat = drxDapFASIFunct_g.readReg16Func(devAddr,
1946 addr, data, flags);
1947 }
1948
1949 return stat;
1950 }
1951
1952 /*============================================================================*/
1953
1954 static DRXStatus_t DRXJ_DAP_ReadReg32(pI2CDeviceAddr_t devAddr,
1955 DRXaddr_t addr,
1956 pu32_t data, DRXflags_t flags)
1957 {
1958 return drxDapFASIFunct_g.readReg32Func(devAddr, addr, data, flags);
1959 }
1960
1961 /*============================================================================*/
1962
1963 static DRXStatus_t DRXJ_DAP_WriteBlock(pI2CDeviceAddr_t devAddr,
1964 DRXaddr_t addr,
1965 u16_t datasize,
1966 pu8_t data, DRXflags_t flags)
1967 {
1968 return drxDapFASIFunct_g.writeBlockFunc(devAddr,
1969 addr, datasize, data, flags);
1970 }
1971
1972 /*============================================================================*/
1973
1974 static DRXStatus_t DRXJ_DAP_WriteReg8(pI2CDeviceAddr_t devAddr,
1975 DRXaddr_t addr,
1976 u8_t data, DRXflags_t flags)
1977 {
1978 return drxDapFASIFunct_g.writeReg8Func(devAddr, addr, data, flags);
1979 }
1980
1981 /*============================================================================*/
1982
1983 /**
1984 * \fn DRXStatus_t DRXJ_DAP_WriteAudReg16
1985 * \brief Write 16 bits audio register
1986 * \param devAddr
1987 * \param addr
1988 * \param data
1989 * \return DRXStatus_t
1990 * \retval DRX_STS_OK Succes
1991 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1992 *
1993 * 16 bits register write access via audio token ring interface.
1994 *
1995 */
1996 static DRXStatus_t DRXJ_DAP_WriteAudReg16(pI2CDeviceAddr_t devAddr,
1997 DRXaddr_t addr, u16_t data)
1998 {
1999 DRXStatus_t stat = DRX_STS_ERROR;
2000
2001 /* No write possible for bank 2, return with error */
2002 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2003 stat = DRX_STS_INVALID_ARG;
2004 } else {
2005 u32_t startTimer = 0;
2006 u32_t currentTimer = 0;
2007 u32_t deltaTimer = 0;
2008 u16_t trStatus = 0;
2009 const DRXaddr_t writeBit = ((DRXaddr_t) 1) << 16;
2010
2011 /* Force write bit */
2012 addr |= writeBit;
2013 startTimer = DRXBSP_HST_Clock();
2014 do {
2015 /* RMW to aud TR IF until request is granted or timeout */
2016 stat = DRXJ_DAP_ReadModifyWriteReg16(devAddr,
2017 addr,
2018 SIO_HI_RA_RAM_S0_RMWBUF__A,
2019 data, &trStatus);
2020 if (stat != DRX_STS_OK) {
2021 break;
2022 };
2023
2024 currentTimer = DRXBSP_HST_Clock();
2025 deltaTimer = currentTimer - startTimer;
2026 if (deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
2027 stat = DRX_STS_ERROR;
2028 break;
2029 };
2030
2031 } while (((trStatus & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
2032 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
2033 ((trStatus & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
2034 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
2035
2036 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2037
2038 return stat;
2039 }
2040
2041 /*============================================================================*/
2042
2043 static DRXStatus_t DRXJ_DAP_WriteReg16(pI2CDeviceAddr_t devAddr,
2044 DRXaddr_t addr,
2045 u16_t data, DRXflags_t flags)
2046 {
2047 DRXStatus_t stat = DRX_STS_ERROR;
2048
2049 /* Check param */
2050 if (devAddr == NULL) {
2051 return DRX_STS_INVALID_ARG;
2052 }
2053
2054 if (IsHandledByAudTrIf(addr)) {
2055 stat = DRXJ_DAP_WriteAudReg16(devAddr, addr, data);
2056 } else {
2057 stat = drxDapFASIFunct_g.writeReg16Func(devAddr,
2058 addr, data, flags);
2059 }
2060
2061 return stat;
2062 }
2063
2064 /*============================================================================*/
2065
2066 static DRXStatus_t DRXJ_DAP_WriteReg32(pI2CDeviceAddr_t devAddr,
2067 DRXaddr_t addr,
2068 u32_t data, DRXflags_t flags)
2069 {
2070 return drxDapFASIFunct_g.writeReg32Func(devAddr, addr, data, flags);
2071 }
2072
2073 /*============================================================================*/
2074
2075 /* Free data ram in SIO HI */
2076 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2077 #define SIO_HI_RA_RAM_USR_END__A 0x420060
2078
2079 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2080 #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2081 #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2082 #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2083
2084 /**
2085 * \fn DRXStatus_t DRXJ_DAP_AtomicReadWriteBlock()
2086 * \brief Basic access routine for atomic read or write access
2087 * \param devAddr pointer to i2c dev address
2088 * \param addr destination/source address
2089 * \param datasize size of data buffer in bytes
2090 * \param data pointer to data buffer
2091 * \return DRXStatus_t
2092 * \retval DRX_STS_OK Succes
2093 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
2094 *
2095 */
2096 static
2097 DRXStatus_t DRXJ_DAP_AtomicReadWriteBlock(pI2CDeviceAddr_t devAddr,
2098 DRXaddr_t addr,
2099 u16_t datasize,
2100 pu8_t data, Bool_t readFlag)
2101 {
2102 DRXJHiCmd_t hiCmd;
2103
2104 u16_t word;
2105 u16_t dummy = 0;
2106 u16_t i = 0;
2107
2108 /* Parameter check */
2109 if ((data == NULL) ||
2110 (devAddr == NULL) || ((datasize % 2) != 0) || ((datasize / 2) > 8)
2111 ) {
2112 return (DRX_STS_INVALID_ARG);
2113 }
2114
2115 /* Set up HI parameters to read or write n bytes */
2116 hiCmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2117 hiCmd.param1 =
2118 (u16_t) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2119 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2120 hiCmd.param2 =
2121 (u16_t) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2122 hiCmd.param3 = (u16_t) ((datasize / 2) - 1);
2123 if (readFlag == FALSE) {
2124 hiCmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2125 } else {
2126 hiCmd.param3 |= DRXJ_HI_ATOMIC_READ;
2127 }
2128 hiCmd.param4 = (u16_t) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2129 DRXDAP_FASI_ADDR2BANK(addr));
2130 hiCmd.param5 = (u16_t) DRXDAP_FASI_ADDR2OFFSET(addr);
2131
2132 if (readFlag == FALSE) {
2133 /* write data to buffer */
2134 for (i = 0; i < (datasize / 2); i++) {
2135
2136 word = ((u16_t) data[2 * i]);
2137 word += (((u16_t) data[(2 * i) + 1]) << 8);
2138 DRXJ_DAP_WriteReg16(devAddr,
2139 (DRXJ_HI_ATOMIC_BUF_START + i),
2140 word, 0);
2141 }
2142 }
2143
2144 CHK_ERROR(HICommand(devAddr, &hiCmd, &dummy));
2145
2146 if (readFlag == TRUE) {
2147 /* read data from buffer */
2148 for (i = 0; i < (datasize / 2); i++) {
2149 DRXJ_DAP_ReadReg16(devAddr,
2150 (DRXJ_HI_ATOMIC_BUF_START + i),
2151 &word, 0);
2152 data[2 * i] = (u8_t) (word & 0xFF);
2153 data[(2 * i) + 1] = (u8_t) (word >> 8);
2154 }
2155 }
2156
2157 return DRX_STS_OK;
2158
2159 rw_error:
2160 return (DRX_STS_ERROR);
2161
2162 }
2163
2164 /*============================================================================*/
2165
2166 /**
2167 * \fn DRXStatus_t DRXJ_DAP_AtomicReadReg32()
2168 * \brief Atomic read of 32 bits words
2169 */
2170 static
2171 DRXStatus_t DRXJ_DAP_AtomicReadReg32(pI2CDeviceAddr_t devAddr,
2172 DRXaddr_t addr,
2173 pu32_t data, DRXflags_t flags)
2174 {
2175 u8_t buf[sizeof(*data)];
2176 DRXStatus_t rc = DRX_STS_ERROR;
2177 u32_t word = 0;
2178
2179 if (!data) {
2180 return DRX_STS_INVALID_ARG;
2181 }
2182
2183 rc = DRXJ_DAP_AtomicReadWriteBlock(devAddr, addr,
2184 sizeof(*data), buf, TRUE);
2185
2186 word = (u32_t) buf[3];
2187 word <<= 8;
2188 word |= (u32_t) buf[2];
2189 word <<= 8;
2190 word |= (u32_t) buf[1];
2191 word <<= 8;
2192 word |= (u32_t) buf[0];
2193
2194 *data = word;
2195
2196 return rc;
2197 }
2198
2199 /*============================================================================*/
2200
2201 /*============================================================================*/
2202 /*== END DRXJ DAP FUNCTIONS ==*/
2203 /*============================================================================*/
2204
2205 /*============================================================================*/
2206 /*============================================================================*/
2207 /*== HOST INTERFACE FUNCTIONS ==*/
2208 /*============================================================================*/
2209 /*============================================================================*/
2210
2211 /**
2212 * \fn DRXStatus_t HICfgCommand()
2213 * \brief Configure HI with settings stored in the demod structure.
2214 * \param demod Demodulator.
2215 * \return DRXStatus_t.
2216 *
2217 * This routine was created because to much orthogonal settings have
2218 * been put into one HI API function (configure). Especially the I2C bridge
2219 * enable/disable should not need re-configuration of the HI.
2220 *
2221 */
2222 static DRXStatus_t HICfgCommand(const pDRXDemodInstance_t demod)
2223 {
2224 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
2225 DRXJHiCmd_t hiCmd;
2226 u16_t result = 0;
2227
2228 extAttr = (pDRXJData_t) demod->myExtAttr;
2229
2230 hiCmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2231 hiCmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2232 hiCmd.param2 = extAttr->HICfgTimingDiv;
2233 hiCmd.param3 = extAttr->HICfgBridgeDelay;
2234 hiCmd.param4 = extAttr->HICfgWakeUpKey;
2235 hiCmd.param5 = extAttr->HICfgCtrl;
2236 hiCmd.param6 = extAttr->HICfgTransmit;
2237
2238 CHK_ERROR(HICommand(demod->myI2CDevAddr, &hiCmd, &result));
2239
2240 /* Reset power down flag (set one call only) */
2241 extAttr->HICfgCtrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2242
2243 return (DRX_STS_OK);
2244
2245 rw_error:
2246 return (DRX_STS_ERROR);
2247 }
2248
2249 /**
2250 * \fn DRXStatus_t HICommand()
2251 * \brief Configure HI with settings stored in the demod structure.
2252 * \param devAddr I2C address.
2253 * \param cmd HI command.
2254 * \param result HI command result.
2255 * \return DRXStatus_t.
2256 *
2257 * Sends command to HI
2258 *
2259 */
2260 static DRXStatus_t
2261 HICommand(const pI2CDeviceAddr_t devAddr, const pDRXJHiCmd_t cmd, pu16_t result)
2262 {
2263 u16_t waitCmd = 0;
2264 u16_t nrRetries = 0;
2265 Bool_t powerdown_cmd = FALSE;
2266
2267 /* Write parameters */
2268 switch (cmd->cmd) {
2269
2270 case SIO_HI_RA_RAM_CMD_CONFIG:
2271 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2272 WR16(devAddr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6);
2273 WR16(devAddr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5);
2274 WR16(devAddr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4);
2275 WR16(devAddr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3);
2276 /* fallthrough */
2277 case SIO_HI_RA_RAM_CMD_BRDCTRL:
2278 WR16(devAddr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2);
2279 WR16(devAddr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1);
2280 /* fallthrough */
2281 case SIO_HI_RA_RAM_CMD_NULL:
2282 /* No parameters */
2283 break;
2284
2285 default:
2286 return (DRX_STS_INVALID_ARG);
2287 break;
2288 }
2289
2290 /* Write command */
2291 WR16(devAddr, SIO_HI_RA_RAM_CMD__A, cmd->cmd);
2292
2293 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET) {
2294 /* Allow for HI to reset */
2295 DRXBSP_HST_Sleep(1);
2296 }
2297
2298 /* Detect power down to ommit reading result */
2299 powerdown_cmd = (Bool_t) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2300 (((cmd->
2301 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2302 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2303 if (powerdown_cmd == FALSE) {
2304 /* Wait until command rdy */
2305 do {
2306 nrRetries++;
2307 if (nrRetries > DRXJ_MAX_RETRIES) {
2308 goto rw_error;
2309 };
2310
2311 RR16(devAddr, SIO_HI_RA_RAM_CMD__A, &waitCmd);
2312 } while (waitCmd != 0);
2313
2314 /* Read result */
2315 RR16(devAddr, SIO_HI_RA_RAM_RES__A, result);
2316
2317 }
2318 /* if ( powerdown_cmd == TRUE ) */
2319 return (DRX_STS_OK);
2320 rw_error:
2321 return (DRX_STS_ERROR);
2322 }
2323
2324 /**
2325 * \fn DRXStatus_t InitHI( const pDRXDemodInstance_t demod )
2326 * \brief Initialise and configurate HI.
2327 * \param demod pointer to demod data.
2328 * \return DRXStatus_t Return status.
2329 * \retval DRX_STS_OK Success.
2330 * \retval DRX_STS_ERROR Failure.
2331 *
2332 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2333 * Need to store configuration in driver because of the way I2C
2334 * bridging is controlled.
2335 *
2336 */
2337 static DRXStatus_t InitHI(const pDRXDemodInstance_t demod)
2338 {
2339 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
2340 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
2341 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
2342
2343 extAttr = (pDRXJData_t) demod->myExtAttr;
2344 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
2345 devAddr = demod->myI2CDevAddr;
2346
2347 /* PATCH for bug 5003, HI ucode v3.1.0 */
2348 WR16(devAddr, 0x4301D7, 0x801);
2349
2350 /* Timing div, 250ns/Psys */
2351 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2352 extAttr->HICfgTimingDiv =
2353 (u16_t) ((commonAttr->sysClockFreq / 1000) * HI_I2C_DELAY) / 1000;
2354 /* Clipping */
2355 if ((extAttr->HICfgTimingDiv) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) {
2356 extAttr->HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2357 }
2358 /* Bridge delay, uses oscilator clock */
2359 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2360 /* SDA brdige delay */
2361 extAttr->HICfgBridgeDelay =
2362 (u16_t) ((commonAttr->oscClockFreq / 1000) * HI_I2C_BRIDGE_DELAY) /
2363 1000;
2364 /* Clipping */
2365 if ((extAttr->HICfgBridgeDelay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
2366 extAttr->HICfgBridgeDelay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2367 }
2368 /* SCL bridge delay, same as SDA for now */
2369 extAttr->HICfgBridgeDelay += ((extAttr->HICfgBridgeDelay) <<
2370 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2371 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2372 not always result into a working solution (barebones worked VI2C failed).
2373 Not setting the bit works in all cases . */
2374 extAttr->HICfgWakeUpKey = DRXJ_WAKE_UP_KEY;
2375 /* port/bridge/power down ctrl */
2376 extAttr->HICfgCtrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2377 /* transit mode time out delay and watch dog divider */
2378 extAttr->HICfgTransmit = SIO_HI_RA_RAM_PAR_6__PRE;
2379
2380 CHK_ERROR(HICfgCommand(demod));
2381
2382 return (DRX_STS_OK);
2383
2384 rw_error:
2385 return (DRX_STS_ERROR);
2386 }
2387
2388 /*============================================================================*/
2389 /*== END HOST INTERFACE FUNCTIONS ==*/
2390 /*============================================================================*/
2391
2392 /*============================================================================*/
2393 /*============================================================================*/
2394 /*== AUXILIARY FUNCTIONS ==*/
2395 /*============================================================================*/
2396 /*============================================================================*/
2397
2398 /**
2399 * \fn DRXStatus_t GetDeviceCapabilities()
2400 * \brief Get and store device capabilities.
2401 * \param demod Pointer to demodulator instance.
2402 * \return DRXStatus_t.
2403 * \return DRX_STS_OK Success
2404 * \retval DRX_STS_ERROR Failure
2405 *
2406 * Depending on pulldowns on MDx pins the following internals are set:
2407 * * commonAttr->oscClockFreq
2408 * * extAttr->hasLNA
2409 * * extAttr->hasNTSC
2410 * * extAttr->hasBTSC
2411 * * extAttr->hasOOB
2412 *
2413 */
2414 static DRXStatus_t GetDeviceCapabilities(pDRXDemodInstance_t demod)
2415 {
2416 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
2417 pDRXJData_t extAttr = (pDRXJData_t) NULL;
2418 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
2419 u16_t sioPdrOhwCfg = 0;
2420 u32_t sioTopJtagidLo = 0;
2421 u16_t bid = 0;
2422
2423 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
2424 extAttr = (pDRXJData_t) demod->myExtAttr;
2425 devAddr = demod->myI2CDevAddr;
2426
2427 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
2428 RR16(devAddr, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
2429 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
2430
2431 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2432 case 0:
2433 /* ignore (bypass ?) */
2434 break;
2435 case 1:
2436 /* 27 MHz */
2437 commonAttr->oscClockFreq = 27000;
2438 break;
2439 case 2:
2440 /* 20.25 MHz */
2441 commonAttr->oscClockFreq = 20250;
2442 break;
2443 case 3:
2444 /* 4 MHz */
2445 commonAttr->oscClockFreq = 4000;
2446 break;
2447 default:
2448 return (DRX_STS_ERROR);
2449 }
2450
2451 /*
2452 Determine device capabilities
2453 Based on pinning v47
2454 */
2455 RR32(devAddr, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
2456 extAttr->mfx = (u8_t) ((sioTopJtagidLo >> 29) & 0xF);
2457
2458 switch ((sioTopJtagidLo >> 12) & 0xFF) {
2459 case 0x31:
2460 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
2461 RR16(devAddr, SIO_PDR_UIO_IN_HI__A, &bid);
2462 bid = (bid >> 10) & 0xf;
2463 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
2464
2465 extAttr->hasLNA = TRUE;
2466 extAttr->hasNTSC = FALSE;
2467 extAttr->hasBTSC = FALSE;
2468 extAttr->hasOOB = FALSE;
2469 extAttr->hasSMATX = TRUE;
2470 extAttr->hasSMARX = FALSE;
2471 extAttr->hasGPIO = FALSE;
2472 extAttr->hasIRQN = FALSE;
2473 break;
2474 case 0x33:
2475 extAttr->hasLNA = FALSE;
2476 extAttr->hasNTSC = FALSE;
2477 extAttr->hasBTSC = FALSE;
2478 extAttr->hasOOB = FALSE;
2479 extAttr->hasSMATX = TRUE;
2480 extAttr->hasSMARX = FALSE;
2481 extAttr->hasGPIO = FALSE;
2482 extAttr->hasIRQN = FALSE;
2483 break;
2484 case 0x45:
2485 extAttr->hasLNA = TRUE;
2486 extAttr->hasNTSC = TRUE;
2487 extAttr->hasBTSC = FALSE;
2488 extAttr->hasOOB = FALSE;
2489 extAttr->hasSMATX = TRUE;
2490 extAttr->hasSMARX = TRUE;
2491 extAttr->hasGPIO = TRUE;
2492 extAttr->hasIRQN = FALSE;
2493 break;
2494 case 0x46:
2495 extAttr->hasLNA = FALSE;
2496 extAttr->hasNTSC = TRUE;
2497 extAttr->hasBTSC = FALSE;
2498 extAttr->hasOOB = FALSE;
2499 extAttr->hasSMATX = TRUE;
2500 extAttr->hasSMARX = TRUE;
2501 extAttr->hasGPIO = TRUE;
2502 extAttr->hasIRQN = FALSE;
2503 break;
2504 case 0x41:
2505 extAttr->hasLNA = TRUE;
2506 extAttr->hasNTSC = TRUE;
2507 extAttr->hasBTSC = TRUE;
2508 extAttr->hasOOB = FALSE;
2509 extAttr->hasSMATX = TRUE;
2510 extAttr->hasSMARX = TRUE;
2511 extAttr->hasGPIO = TRUE;
2512 extAttr->hasIRQN = FALSE;
2513 break;
2514 case 0x43:
2515 extAttr->hasLNA = FALSE;
2516 extAttr->hasNTSC = TRUE;
2517 extAttr->hasBTSC = TRUE;
2518 extAttr->hasOOB = FALSE;
2519 extAttr->hasSMATX = TRUE;
2520 extAttr->hasSMARX = TRUE;
2521 extAttr->hasGPIO = TRUE;
2522 extAttr->hasIRQN = FALSE;
2523 break;
2524 case 0x32:
2525 extAttr->hasLNA = TRUE;
2526 extAttr->hasNTSC = FALSE;
2527 extAttr->hasBTSC = FALSE;
2528 extAttr->hasOOB = TRUE;
2529 extAttr->hasSMATX = TRUE;
2530 extAttr->hasSMARX = TRUE;
2531 extAttr->hasGPIO = TRUE;
2532 extAttr->hasIRQN = TRUE;
2533 break;
2534 case 0x34:
2535 extAttr->hasLNA = FALSE;
2536 extAttr->hasNTSC = TRUE;
2537 extAttr->hasBTSC = TRUE;
2538 extAttr->hasOOB = TRUE;
2539 extAttr->hasSMATX = TRUE;
2540 extAttr->hasSMARX = TRUE;
2541 extAttr->hasGPIO = TRUE;
2542 extAttr->hasIRQN = TRUE;
2543 break;
2544 case 0x42:
2545 extAttr->hasLNA = TRUE;
2546 extAttr->hasNTSC = TRUE;
2547 extAttr->hasBTSC = TRUE;
2548 extAttr->hasOOB = TRUE;
2549 extAttr->hasSMATX = TRUE;
2550 extAttr->hasSMARX = TRUE;
2551 extAttr->hasGPIO = TRUE;
2552 extAttr->hasIRQN = TRUE;
2553 break;
2554 case 0x44:
2555 extAttr->hasLNA = FALSE;
2556 extAttr->hasNTSC = TRUE;
2557 extAttr->hasBTSC = TRUE;
2558 extAttr->hasOOB = TRUE;
2559 extAttr->hasSMATX = TRUE;
2560 extAttr->hasSMARX = TRUE;
2561 extAttr->hasGPIO = TRUE;
2562 extAttr->hasIRQN = TRUE;
2563 break;
2564 default:
2565 /* Unknown device variant */
2566 return (DRX_STS_ERROR);
2567 break;
2568 }
2569
2570 return (DRX_STS_OK);
2571 rw_error:
2572 return (DRX_STS_ERROR);
2573 }
2574
2575 /**
2576 * \fn DRXStatus_t PowerUpDevice()
2577 * \brief Power up device.
2578 * \param demod Pointer to demodulator instance.
2579 * \return DRXStatus_t.
2580 * \return DRX_STS_OK Success
2581 * \retval DRX_STS_ERROR Failure, I2C or max retries reached
2582 *
2583 */
2584
2585 #ifndef DRXJ_MAX_RETRIES_POWERUP
2586 #define DRXJ_MAX_RETRIES_POWERUP 10
2587 #endif
2588
2589 static DRXStatus_t PowerUpDevice(pDRXDemodInstance_t demod)
2590 {
2591 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
2592 u8_t data = 0;
2593 u16_t retryCount = 0;
2594 I2CDeviceAddr_t wakeUpAddr;
2595
2596 devAddr = demod->myI2CDevAddr;
2597 wakeUpAddr.i2cAddr = DRXJ_WAKE_UP_KEY;
2598 wakeUpAddr.i2cDevId = devAddr->i2cDevId;
2599 wakeUpAddr.userData = devAddr->userData;
2600 /* CHK_ERROR macro not used, I2C access may fail in this case: no ack
2601 dummy write must be used to wake uop device, dummy read must be used to
2602 reset HI state machine (avoiding actual writes) */
2603 do {
2604 data = 0;
2605 DRXBSP_I2C_WriteRead(&wakeUpAddr, 1, &data,
2606 (pI2CDeviceAddr_t) (NULL), 0,
2607 (pu8_t) (NULL));
2608 DRXBSP_HST_Sleep(10);
2609 retryCount++;
2610 } while ((DRXBSP_I2C_WriteRead
2611 ((pI2CDeviceAddr_t) (NULL), 0, (pu8_t) (NULL), devAddr, 1,
2612 &data)
2613 != DRX_STS_OK) && (retryCount < DRXJ_MAX_RETRIES_POWERUP));
2614
2615 /* Need some recovery time .... */
2616 DRXBSP_HST_Sleep(10);
2617
2618 if (retryCount == DRXJ_MAX_RETRIES_POWERUP) {
2619 return (DRX_STS_ERROR);
2620 }
2621
2622 return (DRX_STS_OK);
2623 }
2624
2625 /*----------------------------------------------------------------------------*/
2626 /* MPEG Output Configuration Functions - begin */
2627 /*----------------------------------------------------------------------------*/
2628 /**
2629 * \fn DRXStatus_t CtrlSetCfgMPEGOutput()
2630 * \brief Set MPEG output configuration of the device.
2631 * \param devmod Pointer to demodulator instance.
2632 * \param cfgData Pointer to mpeg output configuaration.
2633 * \return DRXStatus_t.
2634 *
2635 * Configure MPEG output parameters.
2636 *
2637 */
2638 static DRXStatus_t
2639 CtrlSetCfgMPEGOutput(pDRXDemodInstance_t demod, pDRXCfgMPEGOutput_t cfgData)
2640 {
2641 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
2642 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
2643 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
2644 u16_t fecOcRegMode = 0;
2645 u16_t fecOcRegIprMode = 0;
2646 u16_t fecOcRegIprInvert = 0;
2647 u32_t maxBitRate = 0;
2648 u32_t rcnRate = 0;
2649 u32_t nrBits = 0;
2650 u16_t sioPdrMdCfg = 0;
2651 /* data mask for the output data byte */
2652 u16_t InvertDataMask =
2653 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2654 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2655 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2656 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2657 /* check arguments */
2658 if ((demod == NULL) || (cfgData == NULL)) {
2659 return (DRX_STS_INVALID_ARG);
2660 }
2661
2662 devAddr = demod->myI2CDevAddr;
2663 extAttr = (pDRXJData_t) demod->myExtAttr;
2664 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
2665
2666 if (cfgData->enableMPEGOutput == TRUE) {
2667 /* quick and dirty patch to set MPEG incase current std is not
2668 producing MPEG */
2669 switch (extAttr->standard) {
2670 case DRX_STANDARD_8VSB:
2671 case DRX_STANDARD_ITU_A:
2672 case DRX_STANDARD_ITU_B:
2673 case DRX_STANDARD_ITU_C:
2674 break;
2675 default:
2676 /* not an MPEG producing std, just store MPEG cfg */
2677 commonAttr->mpegCfg.enableMPEGOutput =
2678 cfgData->enableMPEGOutput;
2679 commonAttr->mpegCfg.insertRSByte =
2680 cfgData->insertRSByte;
2681 commonAttr->mpegCfg.enableParallel =
2682 cfgData->enableParallel;
2683 commonAttr->mpegCfg.invertDATA = cfgData->invertDATA;
2684 commonAttr->mpegCfg.invertERR = cfgData->invertERR;
2685 commonAttr->mpegCfg.invertSTR = cfgData->invertSTR;
2686 commonAttr->mpegCfg.invertVAL = cfgData->invertVAL;
2687 commonAttr->mpegCfg.invertCLK = cfgData->invertCLK;
2688 commonAttr->mpegCfg.staticCLK = cfgData->staticCLK;
2689 commonAttr->mpegCfg.bitrate = cfgData->bitrate;
2690 return (DRX_STS_OK);
2691 }
2692
2693 WR16(devAddr, FEC_OC_OCR_INVERT__A, 0);
2694 switch (extAttr->standard) {
2695 case DRX_STANDARD_8VSB:
2696 WR16(devAddr, FEC_OC_FCT_USAGE__A, 7); /* 2048 bytes fifo ram */
2697 WR16(devAddr, FEC_OC_TMD_CTL_UPD_RATE__A, 10);
2698 WR16(devAddr, FEC_OC_TMD_INT_UPD_RATE__A, 10);
2699 WR16(devAddr, FEC_OC_AVR_PARM_A__A, 5);
2700 WR16(devAddr, FEC_OC_AVR_PARM_B__A, 7);
2701 WR16(devAddr, FEC_OC_RCN_GAIN__A, 10);
2702 /* Low Water Mark for synchronization */
2703 WR16(devAddr, FEC_OC_SNC_LWM__A, 3);
2704 /* High Water Mark for synchronization */
2705 WR16(devAddr, FEC_OC_SNC_HWM__A, 5);
2706 break;
2707 case DRX_STANDARD_ITU_A:
2708 case DRX_STANDARD_ITU_C:
2709 switch (extAttr->constellation) {
2710 case DRX_CONSTELLATION_QAM256:
2711 nrBits = 8;
2712 break;
2713 case DRX_CONSTELLATION_QAM128:
2714 nrBits = 7;
2715 break;
2716 case DRX_CONSTELLATION_QAM64:
2717 nrBits = 6;
2718 break;
2719 case DRX_CONSTELLATION_QAM32:
2720 nrBits = 5;
2721 break;
2722 case DRX_CONSTELLATION_QAM16:
2723 nrBits = 4;
2724 break;
2725 default:
2726 return (DRX_STS_ERROR);
2727 } /* extAttr->constellation */
2728 /* maxBitRate = symbolRate * nrBits * coef */
2729 /* coef = 188/204 */
2730 maxBitRate =
2731 (extAttr->currSymbolRate / 8) * nrBits * 188;
2732 /* pass through b/c Annex A/c need following settings */
2733 case DRX_STANDARD_ITU_B:
2734 WR16(devAddr, FEC_OC_FCT_USAGE__A,
2735 FEC_OC_FCT_USAGE__PRE);
2736 WR16(devAddr, FEC_OC_TMD_CTL_UPD_RATE__A,
2737 FEC_OC_TMD_CTL_UPD_RATE__PRE);
2738 WR16(devAddr, FEC_OC_TMD_INT_UPD_RATE__A, 5);
2739 WR16(devAddr, FEC_OC_AVR_PARM_A__A,
2740 FEC_OC_AVR_PARM_A__PRE);
2741 WR16(devAddr, FEC_OC_AVR_PARM_B__A,
2742 FEC_OC_AVR_PARM_B__PRE);
2743 if (cfgData->staticCLK == TRUE) {
2744 WR16(devAddr, FEC_OC_RCN_GAIN__A, 0xD);
2745 } else {
2746 WR16(devAddr, FEC_OC_RCN_GAIN__A,
2747 FEC_OC_RCN_GAIN__PRE);
2748 }
2749 WR16(devAddr, FEC_OC_SNC_LWM__A, 2);
2750 WR16(devAddr, FEC_OC_SNC_HWM__A, 12);
2751 break;
2752 default:
2753 break;
2754 } /* swtich (standard) */
2755
2756 /* Check insertion of the Reed-Solomon parity bytes */
2757 RR16(devAddr, FEC_OC_MODE__A, &fecOcRegMode);
2758 RR16(devAddr, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2759 if (cfgData->insertRSByte == TRUE) {
2760 /* enable parity symbol forward */
2761 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2762 /* MVAL disable during parity bytes */
2763 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2764 switch (extAttr->standard) {
2765 case DRX_STANDARD_8VSB:
2766 rcnRate = 0x004854D3;
2767 break;
2768 case DRX_STANDARD_ITU_B:
2769 fecOcRegMode |= FEC_OC_MODE_TRANSPARENT__M;
2770 switch (extAttr->constellation) {
2771 case DRX_CONSTELLATION_QAM256:
2772 rcnRate = 0x008945E7;
2773 break;
2774 case DRX_CONSTELLATION_QAM64:
2775 rcnRate = 0x005F64D4;
2776 break;
2777 default:
2778 return (DRX_STS_ERROR);
2779 }
2780 break;
2781 case DRX_STANDARD_ITU_A:
2782 case DRX_STANDARD_ITU_C:
2783 /* insertRSByte = TRUE -> coef = 188/188 -> 1, RS bits are in MPEG output */
2784 rcnRate =
2785 (Frac28
2786 (maxBitRate,
2787 (u32_t) (commonAttr->sysClockFreq / 8))) /
2788 188;
2789 break;
2790 default:
2791 return (DRX_STS_ERROR);
2792 } /* extAttr->standard */
2793 } else { /* insertRSByte == FALSE */
2794
2795 /* disable parity symbol forward */
2796 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2797 /* MVAL enable during parity bytes */
2798 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2799 switch (extAttr->standard) {
2800 case DRX_STANDARD_8VSB:
2801 rcnRate = 0x0041605C;
2802 break;
2803 case DRX_STANDARD_ITU_B:
2804 fecOcRegMode &= (~FEC_OC_MODE_TRANSPARENT__M);
2805 switch (extAttr->constellation) {
2806 case DRX_CONSTELLATION_QAM256:
2807 rcnRate = 0x0082D6A0;
2808 break;
2809 case DRX_CONSTELLATION_QAM64:
2810 rcnRate = 0x005AEC1A;
2811 break;
2812 default:
2813 return (DRX_STS_ERROR);
2814 }
2815 break;
2816 case DRX_STANDARD_ITU_A:
2817 case DRX_STANDARD_ITU_C:
2818 /* insertRSByte = FALSE -> coef = 188/204, RS bits not in MPEG output */
2819 rcnRate =
2820 (Frac28
2821 (maxBitRate,
2822 (u32_t) (commonAttr->sysClockFreq / 8))) /
2823 204;
2824 break;
2825 default:
2826 return (DRX_STS_ERROR);
2827 } /* extAttr->standard */
2828 }
2829
2830 if (cfgData->enableParallel == TRUE) { /* MPEG data output is paralel -> clear ipr_mode[0] */
2831 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2832 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2833 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2834 }
2835
2836 /* Control slective inversion of output bits */
2837 if (cfgData->invertDATA == TRUE) {
2838 fecOcRegIprInvert |= InvertDataMask;
2839 } else {
2840 fecOcRegIprInvert &= (~(InvertDataMask));
2841 }
2842
2843 if (cfgData->invertERR == TRUE) {
2844 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2845 } else {
2846 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2847 }
2848
2849 if (cfgData->invertSTR == TRUE) {
2850 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2851 } else {
2852 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2853 }
2854
2855 if (cfgData->invertVAL == TRUE) {
2856 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2857 } else {
2858 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2859 }
2860
2861 if (cfgData->invertCLK == TRUE) {
2862 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
2863 } else {
2864 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2865 }
2866
2867 if (cfgData->staticCLK == TRUE) { /* Static mode */
2868 u32_t dtoRate = 0;
2869 u32_t bitRate = 0;
2870 u16_t fecOcDtoBurstLen = 0;
2871 u16_t fecOcDtoPeriod = 0;
2872
2873 fecOcDtoBurstLen = FEC_OC_DTO_BURST_LEN__PRE;
2874
2875 switch (extAttr->standard) {
2876 case DRX_STANDARD_8VSB:
2877 fecOcDtoPeriod = 4;
2878 if (cfgData->insertRSByte == TRUE) {
2879 fecOcDtoBurstLen = 208;
2880 }
2881 break;
2882 case DRX_STANDARD_ITU_A:
2883 {
2884 u32_t symbolRateTh = 6400000;
2885 if (cfgData->insertRSByte == TRUE) {
2886 fecOcDtoBurstLen = 204;
2887 symbolRateTh = 5900000;
2888 }
2889 if (extAttr->currSymbolRate >=
2890 symbolRateTh) {
2891 fecOcDtoPeriod = 0;
2892 } else {
2893 fecOcDtoPeriod = 1;
2894 }
2895 }
2896 break;
2897 case DRX_STANDARD_ITU_B:
2898 fecOcDtoPeriod = 1;
2899 if (cfgData->insertRSByte == TRUE) {
2900 fecOcDtoBurstLen = 128;
2901 }
2902 break;
2903 case DRX_STANDARD_ITU_C:
2904 fecOcDtoPeriod = 1;
2905 if (cfgData->insertRSByte == TRUE) {
2906 fecOcDtoBurstLen = 204;
2907 }
2908 break;
2909 default:
2910 return (DRX_STS_ERROR);
2911 }
2912 bitRate =
2913 commonAttr->sysClockFreq * 1000 / (fecOcDtoPeriod +
2914 2);
2915 dtoRate =
2916 Frac28(bitRate, commonAttr->sysClockFreq * 1000);
2917 dtoRate >>= 3;
2918 WR16(devAddr, FEC_OC_DTO_RATE_HI__A,
2919 (u16_t) ((dtoRate >> 16) & FEC_OC_DTO_RATE_HI__M));
2920 WR16(devAddr, FEC_OC_DTO_RATE_LO__A,
2921 (u16_t) (dtoRate & FEC_OC_DTO_RATE_LO_RATE_LO__M));
2922 WR16(devAddr, FEC_OC_DTO_MODE__A,
2923 FEC_OC_DTO_MODE_DYNAMIC__M |
2924 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2925 WR16(devAddr, FEC_OC_FCT_MODE__A,
2926 FEC_OC_FCT_MODE_RAT_ENA__M |
2927 FEC_OC_FCT_MODE_VIRT_ENA__M);
2928 WR16(devAddr, FEC_OC_DTO_BURST_LEN__A,
2929 fecOcDtoBurstLen);
2930 if (extAttr->mpegOutputClockRate !=
2931 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
2932 fecOcDtoPeriod =
2933 extAttr->mpegOutputClockRate - 1;
2934 WR16(devAddr, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2935 } else { /* Dynamic mode */
2936
2937 WR16(devAddr, FEC_OC_DTO_MODE__A,
2938 FEC_OC_DTO_MODE_DYNAMIC__M);
2939 WR16(devAddr, FEC_OC_FCT_MODE__A, 0);
2940 }
2941
2942 WR32(devAddr, FEC_OC_RCN_CTL_RATE_LO__A, rcnRate);
2943
2944 /* Write appropriate registers with requested configuration */
2945 WR16(devAddr, FEC_OC_MODE__A, fecOcRegMode);
2946 WR16(devAddr, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2947 WR16(devAddr, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
2948
2949 /* enabling for both parallel and serial now */
2950 /* Write magic word to enable pdr reg write */
2951 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
2952 /* Set MPEG TS pads to outputmode */
2953 WR16(devAddr, SIO_PDR_MSTRT_CFG__A, 0x0013);
2954 WR16(devAddr, SIO_PDR_MERR_CFG__A, 0x0013);
2955 WR16(devAddr, SIO_PDR_MCLK_CFG__A,
2956 MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B
2957 | 0x03 << SIO_PDR_MCLK_CFG_MODE__B);
2958 WR16(devAddr, SIO_PDR_MVAL_CFG__A, 0x0013);
2959 sioPdrMdCfg =
2960 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
2961 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
2962 WR16(devAddr, SIO_PDR_MD0_CFG__A, sioPdrMdCfg);
2963 if (cfgData->enableParallel == TRUE) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
2964 sioPdrMdCfg =
2965 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
2966 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
2967 SIO_PDR_MD0_CFG_MODE__B;
2968 WR16(devAddr, SIO_PDR_MD0_CFG__A, sioPdrMdCfg);
2969 WR16(devAddr, SIO_PDR_MD1_CFG__A, sioPdrMdCfg);
2970 WR16(devAddr, SIO_PDR_MD2_CFG__A, sioPdrMdCfg);
2971 WR16(devAddr, SIO_PDR_MD3_CFG__A, sioPdrMdCfg);
2972 WR16(devAddr, SIO_PDR_MD4_CFG__A, sioPdrMdCfg);
2973 WR16(devAddr, SIO_PDR_MD5_CFG__A, sioPdrMdCfg);
2974 WR16(devAddr, SIO_PDR_MD6_CFG__A, sioPdrMdCfg);
2975 WR16(devAddr, SIO_PDR_MD7_CFG__A, sioPdrMdCfg);
2976 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
2977 WR16(devAddr, SIO_PDR_MD1_CFG__A, 0x0000);
2978 WR16(devAddr, SIO_PDR_MD2_CFG__A, 0x0000);
2979 WR16(devAddr, SIO_PDR_MD3_CFG__A, 0x0000);
2980 WR16(devAddr, SIO_PDR_MD4_CFG__A, 0x0000);
2981 WR16(devAddr, SIO_PDR_MD5_CFG__A, 0x0000);
2982 WR16(devAddr, SIO_PDR_MD6_CFG__A, 0x0000);
2983 WR16(devAddr, SIO_PDR_MD7_CFG__A, 0x0000);
2984 }
2985 /* Enable Monitor Bus output over MPEG pads and ctl input */
2986 WR16(devAddr, SIO_PDR_MON_CFG__A, 0x0000);
2987 /* Write nomagic word to enable pdr reg write */
2988 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0x0000);
2989 } else {
2990 /* Write magic word to enable pdr reg write */
2991 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
2992 /* Set MPEG TS pads to inputmode */
2993 WR16(devAddr, SIO_PDR_MSTRT_CFG__A, 0x0000);
2994 WR16(devAddr, SIO_PDR_MERR_CFG__A, 0x0000);
2995 WR16(devAddr, SIO_PDR_MCLK_CFG__A, 0x0000);
2996 WR16(devAddr, SIO_PDR_MVAL_CFG__A, 0x0000);
2997 WR16(devAddr, SIO_PDR_MD0_CFG__A, 0x0000);
2998 WR16(devAddr, SIO_PDR_MD1_CFG__A, 0x0000);
2999 WR16(devAddr, SIO_PDR_MD2_CFG__A, 0x0000);
3000 WR16(devAddr, SIO_PDR_MD3_CFG__A, 0x0000);
3001 WR16(devAddr, SIO_PDR_MD4_CFG__A, 0x0000);
3002 WR16(devAddr, SIO_PDR_MD5_CFG__A, 0x0000);
3003 WR16(devAddr, SIO_PDR_MD6_CFG__A, 0x0000);
3004 WR16(devAddr, SIO_PDR_MD7_CFG__A, 0x0000);
3005 /* Enable Monitor Bus output over MPEG pads and ctl input */
3006 WR16(devAddr, SIO_PDR_MON_CFG__A, 0x0000);
3007 /* Write nomagic word to enable pdr reg write */
3008 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3009 }
3010
3011 /* save values for restore after re-acquire */
3012 commonAttr->mpegCfg.enableMPEGOutput = cfgData->enableMPEGOutput;
3013 commonAttr->mpegCfg.insertRSByte = cfgData->insertRSByte;
3014 commonAttr->mpegCfg.enableParallel = cfgData->enableParallel;
3015 commonAttr->mpegCfg.invertDATA = cfgData->invertDATA;
3016 commonAttr->mpegCfg.invertERR = cfgData->invertERR;
3017 commonAttr->mpegCfg.invertSTR = cfgData->invertSTR;
3018 commonAttr->mpegCfg.invertVAL = cfgData->invertVAL;
3019 commonAttr->mpegCfg.invertCLK = cfgData->invertCLK;
3020 commonAttr->mpegCfg.staticCLK = cfgData->staticCLK;
3021 commonAttr->mpegCfg.bitrate = cfgData->bitrate;
3022
3023 return (DRX_STS_OK);
3024 rw_error:
3025 return (DRX_STS_ERROR);
3026 }
3027
3028 /*----------------------------------------------------------------------------*/
3029
3030 /**
3031 * \fn DRXStatus_t CtrlGetCfgMPEGOutput()
3032 * \brief Get MPEG output configuration of the device.
3033 * \param devmod Pointer to demodulator instance.
3034 * \param cfgData Pointer to MPEG output configuaration struct.
3035 * \return DRXStatus_t.
3036 *
3037 * Retrieve MPEG output configuartion.
3038 *
3039 */
3040 static DRXStatus_t
3041 CtrlGetCfgMPEGOutput(pDRXDemodInstance_t demod, pDRXCfgMPEGOutput_t cfgData)
3042 {
3043 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
3044 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
3045 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
3046 u32_t rateReg = 0;
3047 u32_t data64Hi = 0;
3048 u32_t data64Lo = 0;
3049
3050 if (cfgData == NULL) {
3051 return (DRX_STS_INVALID_ARG);
3052 }
3053 devAddr = demod->myI2CDevAddr;
3054 commonAttr = demod->myCommonAttr;
3055
3056 cfgData->enableMPEGOutput = commonAttr->mpegCfg.enableMPEGOutput;
3057 cfgData->insertRSByte = commonAttr->mpegCfg.insertRSByte;
3058 cfgData->enableParallel = commonAttr->mpegCfg.enableParallel;
3059 cfgData->invertDATA = commonAttr->mpegCfg.invertDATA;
3060 cfgData->invertERR = commonAttr->mpegCfg.invertERR;
3061 cfgData->invertSTR = commonAttr->mpegCfg.invertSTR;
3062 cfgData->invertVAL = commonAttr->mpegCfg.invertVAL;
3063 cfgData->invertCLK = commonAttr->mpegCfg.invertCLK;
3064 cfgData->staticCLK = commonAttr->mpegCfg.staticCLK;
3065 cfgData->bitrate = 0;
3066
3067 CHK_ERROR(CtrlLockStatus(demod, &lockStatus));
3068 if ((lockStatus == DRX_LOCKED)) {
3069 RR32(devAddr, FEC_OC_RCN_DYN_RATE_LO__A, &rateReg);
3070 /* Frcn_rate = rateReg * Fsys / 2 ^ 25 */
3071 Mult32(rateReg, commonAttr->sysClockFreq * 1000, &data64Hi,
3072 &data64Lo);
3073 cfgData->bitrate = (data64Hi << 7) | (data64Lo >> 25);
3074 }
3075
3076 return (DRX_STS_OK);
3077 rw_error:
3078 return (DRX_STS_ERROR);
3079 }
3080
3081 /*----------------------------------------------------------------------------*/
3082 /* MPEG Output Configuration Functions - end */
3083 /*----------------------------------------------------------------------------*/
3084
3085 /*----------------------------------------------------------------------------*/
3086 /* miscellaneous configuartions - begin */
3087 /*----------------------------------------------------------------------------*/
3088
3089 /**
3090 * \fn DRXStatus_t SetMPEGTEIHandling()
3091 * \brief Activate MPEG TEI handling settings.
3092 * \param devmod Pointer to demodulator instance.
3093 * \return DRXStatus_t.
3094 *
3095 * This routine should be called during a set channel of QAM/VSB
3096 *
3097 */
3098 static DRXStatus_t SetMPEGTEIHandling(pDRXDemodInstance_t demod)
3099 {
3100 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3101 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
3102 u16_t fecOcDprMode = 0;
3103 u16_t fecOcSncMode = 0;
3104 u16_t fecOcEmsMode = 0;
3105
3106 devAddr = demod->myI2CDevAddr;
3107 extAttr = (pDRXJData_t) demod->myExtAttr;
3108
3109 RR16(devAddr, FEC_OC_DPR_MODE__A, &fecOcDprMode);
3110 RR16(devAddr, FEC_OC_SNC_MODE__A, &fecOcSncMode);
3111 RR16(devAddr, FEC_OC_EMS_MODE__A, &fecOcEmsMode);
3112
3113 /* reset to default, allow TEI bit to be changed */
3114 fecOcDprMode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3115 fecOcSncMode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3116 FEC_OC_SNC_MODE_CORR_DISABLE__M));
3117 fecOcEmsMode &= (~FEC_OC_EMS_MODE_MODE__M);
3118
3119 if (extAttr->disableTEIhandling == TRUE) {
3120 /* do not change TEI bit */
3121 fecOcDprMode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3122 fecOcSncMode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3123 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3124 fecOcEmsMode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3125 }
3126
3127 WR16(devAddr, FEC_OC_DPR_MODE__A, fecOcDprMode);
3128 WR16(devAddr, FEC_OC_SNC_MODE__A, fecOcSncMode);
3129 WR16(devAddr, FEC_OC_EMS_MODE__A, fecOcEmsMode);
3130
3131 return (DRX_STS_OK);
3132 rw_error:
3133 return (DRX_STS_ERROR);
3134 }
3135
3136 /*----------------------------------------------------------------------------*/
3137 /**
3138 * \fn DRXStatus_t BitReverseMPEGOutput()
3139 * \brief Set MPEG output bit-endian settings.
3140 * \param devmod Pointer to demodulator instance.
3141 * \return DRXStatus_t.
3142 *
3143 * This routine should be called during a set channel of QAM/VSB
3144 *
3145 */
3146 static DRXStatus_t BitReverseMPEGOutput(pDRXDemodInstance_t demod)
3147 {
3148 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3149 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
3150 u16_t fecOcIprMode = 0;
3151
3152 devAddr = demod->myI2CDevAddr;
3153 extAttr = (pDRXJData_t) demod->myExtAttr;
3154
3155 RR16(devAddr, FEC_OC_IPR_MODE__A, &fecOcIprMode);
3156
3157 /* reset to default (normal bit order) */
3158 fecOcIprMode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3159
3160 if (extAttr->bitReverseMpegOutout == TRUE) {
3161 /* reverse bit order */
3162 fecOcIprMode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3163 }
3164
3165 WR16(devAddr, FEC_OC_IPR_MODE__A, fecOcIprMode);
3166
3167 return (DRX_STS_OK);
3168 rw_error:
3169 return (DRX_STS_ERROR);
3170 }
3171
3172 /*----------------------------------------------------------------------------*/
3173 /**
3174 * \fn DRXStatus_t SetMPEGOutputClockRate()
3175 * \brief Set MPEG output clock rate.
3176 * \param devmod Pointer to demodulator instance.
3177 * \return DRXStatus_t.
3178 *
3179 * This routine should be called during a set channel of QAM/VSB
3180 *
3181 */
3182 static DRXStatus_t SetMPEGOutputClockRate(pDRXDemodInstance_t demod)
3183 {
3184 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3185 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
3186
3187 devAddr = demod->myI2CDevAddr;
3188 extAttr = (pDRXJData_t) demod->myExtAttr;
3189
3190 if (extAttr->mpegOutputClockRate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3191 WR16(devAddr, FEC_OC_DTO_PERIOD__A,
3192 extAttr->mpegOutputClockRate - 1);
3193 }
3194
3195 return (DRX_STS_OK);
3196 rw_error:
3197 return (DRX_STS_ERROR);
3198 }
3199
3200 /*----------------------------------------------------------------------------*/
3201 /**
3202 * \fn DRXStatus_t SetMPEGStartWidth()
3203 * \brief Set MPEG start width.
3204 * \param devmod Pointer to demodulator instance.
3205 * \return DRXStatus_t.
3206 *
3207 * This routine should be called during a set channel of QAM/VSB
3208 *
3209 */
3210 static DRXStatus_t SetMPEGStartWidth(pDRXDemodInstance_t demod)
3211 {
3212 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3213 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
3214 u16_t fecOcCommMb = 0;
3215 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) NULL;
3216
3217 devAddr = demod->myI2CDevAddr;
3218 extAttr = (pDRXJData_t) demod->myExtAttr;
3219 commonAttr = demod->myCommonAttr;
3220
3221 if ((commonAttr->mpegCfg.staticCLK == TRUE)
3222 && (commonAttr->mpegCfg.enableParallel == FALSE)) {
3223 RR16(devAddr, FEC_OC_COMM_MB__A, &fecOcCommMb);
3224 fecOcCommMb &= ~FEC_OC_COMM_MB_CTL_ON;
3225 if (extAttr->mpegStartWidth == DRXJ_MPEG_START_WIDTH_8CLKCYC) {
3226 fecOcCommMb |= FEC_OC_COMM_MB_CTL_ON;
3227 }
3228 WR16(devAddr, FEC_OC_COMM_MB__A, fecOcCommMb);
3229 }
3230
3231 return (DRX_STS_OK);
3232 rw_error:
3233 return (DRX_STS_ERROR);
3234 }
3235
3236 /*----------------------------------------------------------------------------*/
3237 /**
3238 * \fn DRXStatus_t CtrlSetCfgMpegOutputMisc()
3239 * \brief Set miscellaneous configuartions
3240 * \param devmod Pointer to demodulator instance.
3241 * \param cfgData pDRXJCfgMisc_t
3242 * \return DRXStatus_t.
3243 *
3244 * This routine can be used to set configuartion options that are DRXJ
3245 * specific and/or added to the requirements at a late stage.
3246 *
3247 */
3248 static DRXStatus_t
3249 CtrlSetCfgMpegOutputMisc(pDRXDemodInstance_t demod,
3250 pDRXJCfgMpegOutputMisc_t cfgData)
3251 {
3252 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3253
3254 if (cfgData == NULL) {
3255 return (DRX_STS_INVALID_ARG);
3256 }
3257
3258 extAttr = (pDRXJData_t) demod->myExtAttr;
3259
3260 /*
3261 Set disable TEI bit handling flag.
3262 TEI must be left untouched by device in case of BER measurements using
3263 external equipment that is unable to ignore the TEI bit in the TS.
3264 Default will FALSE (enable TEI bit handling).
3265 Reverse output bit order. Default is FALSE (msb on MD7 (parallel) or out first (serial)).
3266 Set clock rate. Default is auto that is derived from symbol rate.
3267 The flags and values will also be used to set registers during a set channel.
3268 */
3269 extAttr->disableTEIhandling = cfgData->disableTEIHandling;
3270 extAttr->bitReverseMpegOutout = cfgData->bitReverseMpegOutout;
3271 extAttr->mpegOutputClockRate = cfgData->mpegOutputClockRate;
3272 extAttr->mpegStartWidth = cfgData->mpegStartWidth;
3273 /* Don't care what the active standard is, activate setting immediatly */
3274 CHK_ERROR(SetMPEGTEIHandling(demod));
3275 CHK_ERROR(BitReverseMPEGOutput(demod));
3276 CHK_ERROR(SetMPEGOutputClockRate(demod));
3277 CHK_ERROR(SetMPEGStartWidth(demod));
3278
3279 return (DRX_STS_OK);
3280 rw_error:
3281 return (DRX_STS_ERROR);
3282 }
3283
3284 /*----------------------------------------------------------------------------*/
3285
3286 /**
3287 * \fn DRXStatus_t CtrlGetCfgMpegOutputMisc()
3288 * \brief Get miscellaneous configuartions.
3289 * \param devmod Pointer to demodulator instance.
3290 * \param cfgData Pointer to DRXJCfgMisc_t.
3291 * \return DRXStatus_t.
3292 *
3293 * This routine can be used to retreive the current setting of the configuartion
3294 * options that are DRXJ specific and/or added to the requirements at a
3295 * late stage.
3296 *
3297 */
3298 static DRXStatus_t
3299 CtrlGetCfgMpegOutputMisc(pDRXDemodInstance_t demod,
3300 pDRXJCfgMpegOutputMisc_t cfgData)
3301 {
3302 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3303 u16_t data = 0;
3304
3305 if (cfgData == NULL) {
3306 return (DRX_STS_INVALID_ARG);
3307 }
3308
3309 extAttr = (pDRXJData_t) demod->myExtAttr;
3310 cfgData->disableTEIHandling = extAttr->disableTEIhandling;
3311 cfgData->bitReverseMpegOutout = extAttr->bitReverseMpegOutout;
3312 cfgData->mpegStartWidth = extAttr->mpegStartWidth;
3313 if (extAttr->mpegOutputClockRate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3314 cfgData->mpegOutputClockRate = extAttr->mpegOutputClockRate;
3315 } else {
3316 RR16(demod->myI2CDevAddr, FEC_OC_DTO_PERIOD__A, &data);
3317 cfgData->mpegOutputClockRate =
3318 (DRXJMpegOutputClockRate_t) (data + 1);
3319 }
3320
3321 return (DRX_STS_OK);
3322 rw_error:
3323 return (DRX_STS_ERROR);
3324 }
3325
3326 /*----------------------------------------------------------------------------*/
3327
3328 /**
3329 * \fn DRXStatus_t CtrlGetCfgHwCfg()
3330 * \brief Get HW configuartions.
3331 * \param devmod Pointer to demodulator instance.
3332 * \param cfgData Pointer to Bool.
3333 * \return DRXStatus_t.
3334 *
3335 * This routine can be used to retreive the current setting of the configuartion
3336 * options that are DRXJ specific and/or added to the requirements at a
3337 * late stage.
3338 *
3339 */
3340 static DRXStatus_t
3341 CtrlGetCfgHwCfg(pDRXDemodInstance_t demod, pDRXJCfgHwCfg_t cfgData)
3342 {
3343 u16_t data = 0;
3344 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3345
3346 if (cfgData == NULL) {
3347 return (DRX_STS_INVALID_ARG);
3348 }
3349
3350 extAttr = (pDRXJData_t) demod->myExtAttr;
3351 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
3352 RR16(demod->myI2CDevAddr, SIO_PDR_OHW_CFG__A, &data);
3353 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3354
3355 cfgData->i2cSpeed = (DRXJI2CSpeed_t) ((data >> 6) & 0x1);
3356 cfgData->xtalFreq = (DRXJXtalFreq_t) (data & 0x3);
3357
3358 return (DRX_STS_OK);
3359 rw_error:
3360 return (DRX_STS_ERROR);
3361 }
3362
3363 /*----------------------------------------------------------------------------*/
3364 /* miscellaneous configuartions - end */
3365 /*----------------------------------------------------------------------------*/
3366
3367 /*----------------------------------------------------------------------------*/
3368 /* UIO Configuration Functions - begin */
3369 /*----------------------------------------------------------------------------*/
3370 /**
3371 * \fn DRXStatus_t CtrlSetUIOCfg()
3372 * \brief Configure modus oprandi UIO.
3373 * \param demod Pointer to demodulator instance.
3374 * \param UIOCfg Pointer to a configuration setting for a certain UIO.
3375 * \return DRXStatus_t.
3376 */
3377 static DRXStatus_t CtrlSetUIOCfg(pDRXDemodInstance_t demod, pDRXUIOCfg_t UIOCfg)
3378 {
3379 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3380
3381 if ((UIOCfg == NULL) || (demod == NULL)) {
3382 return DRX_STS_INVALID_ARG;
3383 }
3384 extAttr = (pDRXJData_t) demod->myExtAttr;
3385
3386 /* Write magic word to enable pdr reg write */
3387 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3388 switch (UIOCfg->uio) {
3389 /*====================================================================*/
3390 case DRX_UIO1:
3391 /* DRX_UIO1: SMA_TX UIO-1 */
3392 if (extAttr->hasSMATX != TRUE)
3393 return DRX_STS_ERROR;
3394 switch (UIOCfg->mode) {
3395 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3396 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3397 case DRX_UIO_MODE_READWRITE:
3398 extAttr->uioSmaTxMode = UIOCfg->mode;
3399 break;
3400 case DRX_UIO_MODE_DISABLE:
3401 extAttr->uioSmaTxMode = UIOCfg->mode;
3402 /* pad configuration register is set 0 - input mode */
3403 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, 0);
3404 break;
3405 default:
3406 return DRX_STS_INVALID_ARG;
3407 } /* switch ( UIOCfg->mode ) */
3408 break;
3409 /*====================================================================*/
3410 case DRX_UIO2:
3411 /* DRX_UIO2: SMA_RX UIO-2 */
3412 if (extAttr->hasSMARX != TRUE)
3413 return DRX_STS_ERROR;
3414 switch (UIOCfg->mode) {
3415 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3416 case DRX_UIO_MODE_READWRITE:
3417 extAttr->uioSmaRxMode = UIOCfg->mode;
3418 break;
3419 case DRX_UIO_MODE_DISABLE:
3420 extAttr->uioSmaRxMode = UIOCfg->mode;
3421 /* pad configuration register is set 0 - input mode */
3422 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, 0);
3423 break;
3424 default:
3425 return DRX_STS_INVALID_ARG;
3426 break;
3427 } /* switch ( UIOCfg->mode ) */
3428 break;
3429 /*====================================================================*/
3430 case DRX_UIO3:
3431 /* DRX_UIO3: GPIO UIO-3 */
3432 if (extAttr->hasGPIO != TRUE)
3433 return DRX_STS_ERROR;
3434 switch (UIOCfg->mode) {
3435 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3436 case DRX_UIO_MODE_READWRITE:
3437 extAttr->uioGPIOMode = UIOCfg->mode;
3438 break;
3439 case DRX_UIO_MODE_DISABLE:
3440 extAttr->uioGPIOMode = UIOCfg->mode;
3441 /* pad configuration register is set 0 - input mode */
3442 WR16(demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, 0);
3443 break;
3444 default:
3445 return DRX_STS_INVALID_ARG;
3446 break;
3447 } /* switch ( UIOCfg->mode ) */
3448 break;
3449 /*====================================================================*/
3450 case DRX_UIO4:
3451 /* DRX_UIO4: IRQN UIO-4 */
3452 if (extAttr->hasIRQN != TRUE)
3453 return DRX_STS_ERROR;
3454 switch (UIOCfg->mode) {
3455 case DRX_UIO_MODE_READWRITE:
3456 extAttr->uioIRQNMode = UIOCfg->mode;
3457 break;
3458 case DRX_UIO_MODE_DISABLE:
3459 /* pad configuration register is set 0 - input mode */
3460 WR16(demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, 0);
3461 extAttr->uioIRQNMode = UIOCfg->mode;
3462 break;
3463 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3464 default:
3465 return DRX_STS_INVALID_ARG;
3466 break;
3467 } /* switch ( UIOCfg->mode ) */
3468 break;
3469 /*====================================================================*/
3470 default:
3471 return DRX_STS_INVALID_ARG;
3472 } /* switch ( UIOCfg->uio ) */
3473
3474 /* Write magic word to disable pdr reg write */
3475 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3476
3477 return (DRX_STS_OK);
3478 rw_error:
3479 return (DRX_STS_ERROR);
3480 }
3481
3482 /*============================================================================*/
3483 /**
3484 * \fn DRXStatus_t CtrlGetUIOCfg()
3485 * \brief Get modus oprandi UIO.
3486 * \param demod Pointer to demodulator instance.
3487 * \param UIOCfg Pointer to a configuration setting for a certain UIO.
3488 * \return DRXStatus_t.
3489 */
3490 static DRXStatus_t CtrlGetUIOCfg(pDRXDemodInstance_t demod, pDRXUIOCfg_t UIOCfg)
3491 {
3492
3493 pDRXJData_t extAttr = (pDRXJData_t) NULL;
3494 pDRXUIOMode_t UIOMode[4] = { NULL };
3495 pBool_t UIOAvailable[4] = { NULL };
3496
3497 extAttr = demod->myExtAttr;
3498
3499 UIOMode[DRX_UIO1] = &extAttr->uioSmaTxMode;
3500 UIOMode[DRX_UIO2] = &extAttr->uioSmaRxMode;
3501 UIOMode[DRX_UIO3] = &extAttr->uioGPIOMode;
3502 UIOMode[DRX_UIO4] = &extAttr->uioIRQNMode;
3503
3504 UIOAvailable[DRX_UIO1] = &extAttr->hasSMATX;
3505 UIOAvailable[DRX_UIO2] = &extAttr->hasSMARX;
3506 UIOAvailable[DRX_UIO3] = &extAttr->hasGPIO;
3507 UIOAvailable[DRX_UIO4] = &extAttr->hasIRQN;
3508
3509 if (UIOCfg == NULL) {
3510 return DRX_STS_INVALID_ARG;
3511 }
3512
3513 if ((UIOCfg->uio > DRX_UIO4) || (UIOCfg->uio < DRX_UIO1)) {
3514 return DRX_STS_INVALID_ARG;
3515 }
3516
3517 if (*UIOAvailable[UIOCfg->uio] == FALSE) {
3518 return DRX_STS_ERROR;
3519 }
3520
3521 UIOCfg->mode = *UIOMode[UIOCfg->uio];
3522
3523 return DRX_STS_OK;
3524 }
3525
3526 /**
3527 * \fn DRXStatus_t CtrlUIOWrite()
3528 * \brief Write to a UIO.
3529 * \param demod Pointer to demodulator instance.
3530 * \param UIOData Pointer to data container for a certain UIO.
3531 * \return DRXStatus_t.
3532 */
3533 static DRXStatus_t
3534 CtrlUIOWrite(pDRXDemodInstance_t demod, pDRXUIOData_t UIOData)
3535 {
3536 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3537 u16_t pinCfgValue = 0;
3538 u16_t value = 0;
3539
3540 if ((UIOData == NULL) || (demod == NULL)) {
3541 return DRX_STS_INVALID_ARG;
3542 }
3543
3544 extAttr = (pDRXJData_t) demod->myExtAttr;
3545
3546 /* Write magic word to enable pdr reg write */
3547 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3548 switch (UIOData->uio) {
3549 /*====================================================================*/
3550 case DRX_UIO1:
3551 /* DRX_UIO1: SMA_TX UIO-1 */
3552 if (extAttr->hasSMATX != TRUE)
3553 return DRX_STS_ERROR;
3554 if ((extAttr->uioSmaTxMode != DRX_UIO_MODE_READWRITE)
3555 && (extAttr->uioSmaTxMode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3556 return DRX_STS_ERROR;
3557 }
3558 pinCfgValue = 0;
3559 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3560 pinCfgValue |= 0x0113;
3561 /* io_pad_cfg_mode output mode is drive always */
3562 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3563
3564 /* write to io pad configuration register - output mode */
3565 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, pinCfgValue);
3566
3567 /* use corresponding bit in io data output registar */
3568 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value);
3569 if (UIOData->value == FALSE) {
3570 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3571 } else {
3572 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3573 }
3574 /* write back to io data output register */
3575 WR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value);
3576 break;
3577 /*======================================================================*/
3578 case DRX_UIO2:
3579 /* DRX_UIO2: SMA_RX UIO-2 */
3580 if (extAttr->hasSMARX != TRUE)
3581 return DRX_STS_ERROR;
3582 if (extAttr->uioSmaRxMode != DRX_UIO_MODE_READWRITE) {
3583 return DRX_STS_ERROR;
3584 }
3585 pinCfgValue = 0;
3586 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3587 pinCfgValue |= 0x0113;
3588 /* io_pad_cfg_mode output mode is drive always */
3589 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3590
3591 /* write to io pad configuration register - output mode */
3592 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, pinCfgValue);
3593
3594 /* use corresponding bit in io data output registar */
3595 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value);
3596 if (UIOData->value == FALSE) {
3597 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3598 } else {
3599 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
3600 }
3601 /* write back to io data output register */
3602 WR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value);
3603 break;
3604 /*====================================================================*/
3605 case DRX_UIO3:
3606 /* DRX_UIO3: ASEL UIO-3 */
3607 if (extAttr->hasGPIO != TRUE)
3608 return DRX_STS_ERROR;
3609 if (extAttr->uioGPIOMode != DRX_UIO_MODE_READWRITE) {
3610 return DRX_STS_ERROR;
3611 }
3612 pinCfgValue = 0;
3613 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3614 pinCfgValue |= 0x0113;
3615 /* io_pad_cfg_mode output mode is drive always */
3616 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3617
3618 /* write to io pad configuration register - output mode */
3619 WR16(demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, pinCfgValue);
3620
3621 /* use corresponding bit in io data output registar */
3622 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_HI__A, &value);
3623 if (UIOData->value == FALSE) {
3624 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
3625 } else {
3626 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
3627 }
3628 /* write back to io data output register */
3629 WR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_HI__A, value);
3630 break;
3631 /*=====================================================================*/
3632 case DRX_UIO4:
3633 /* DRX_UIO4: IRQN UIO-4 */
3634 if (extAttr->hasIRQN != TRUE)
3635 return DRX_STS_ERROR;
3636
3637 if (extAttr->uioIRQNMode != DRX_UIO_MODE_READWRITE) {
3638 return DRX_STS_ERROR;
3639 }
3640 pinCfgValue = 0;
3641 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3642 pinCfgValue |= 0x0113;
3643 /* io_pad_cfg_mode output mode is drive always */
3644 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3645
3646 /* write to io pad configuration register - output mode */
3647 WR16(demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, pinCfgValue);
3648
3649 /* use corresponding bit in io data output registar */
3650 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value);
3651 if (UIOData->value == FALSE) {
3652 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
3653 } else {
3654 value |= 0x1000; /* write one to 12th bit - 4th UIO */
3655 }
3656 /* write back to io data output register */
3657 WR16(demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value);
3658 break;
3659 /*=====================================================================*/
3660 default:
3661 return DRX_STS_INVALID_ARG;
3662 } /* switch ( UIOData->uio ) */
3663
3664 /* Write magic word to disable pdr reg write */
3665 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3666
3667 return (DRX_STS_OK);
3668 rw_error:
3669 return (DRX_STS_ERROR);
3670 }
3671
3672 /**
3673 *\fn DRXStatus_t CtrlUIORead
3674 *\brief Read from a UIO.
3675 * \param demod Pointer to demodulator instance.
3676 * \param UIOData Pointer to data container for a certain UIO.
3677 * \return DRXStatus_t.
3678 */
3679 static DRXStatus_t CtrlUIORead(pDRXDemodInstance_t demod, pDRXUIOData_t UIOData)
3680 {
3681 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
3682 u16_t pinCfgValue = 0;
3683 u16_t value = 0;
3684
3685 if ((UIOData == NULL) || (demod == NULL)) {
3686 return DRX_STS_INVALID_ARG;
3687 }
3688
3689 extAttr = (pDRXJData_t) demod->myExtAttr;
3690
3691 /* Write magic word to enable pdr reg write */
3692 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3693 switch (UIOData->uio) {
3694 /*====================================================================*/
3695 case DRX_UIO1:
3696 /* DRX_UIO1: SMA_TX UIO-1 */
3697 if (extAttr->hasSMATX != TRUE)
3698 return DRX_STS_ERROR;
3699
3700 if (extAttr->uioSmaTxMode != DRX_UIO_MODE_READWRITE) {
3701 return DRX_STS_ERROR;
3702 }
3703 pinCfgValue = 0;
3704 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3705 pinCfgValue |= 0x0110;
3706 /* io_pad_cfg_mode output mode is drive always */
3707 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3708
3709 /* write to io pad configuration register - input mode */
3710 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, pinCfgValue);
3711
3712 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value);
3713 if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */
3714 UIOData->value = TRUE;
3715 } else {
3716 UIOData->value = FALSE;
3717 }
3718 break;
3719 /*======================================================================*/
3720 case DRX_UIO2:
3721 /* DRX_UIO2: SMA_RX UIO-2 */
3722 if (extAttr->hasSMARX != TRUE)
3723 return DRX_STS_ERROR;
3724
3725 if (extAttr->uioSmaRxMode != DRX_UIO_MODE_READWRITE) {
3726 return DRX_STS_ERROR;
3727 }
3728 pinCfgValue = 0;
3729 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3730 pinCfgValue |= 0x0110;
3731 /* io_pad_cfg_mode output mode is drive always */
3732 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3733
3734 /* write to io pad configuration register - input mode */
3735 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, pinCfgValue);
3736
3737 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value);
3738
3739 if ((value & 0x4000) != 0) { /* check 14th bit - 2nd UIO */
3740 UIOData->value = TRUE;
3741 } else {
3742 UIOData->value = FALSE;
3743 }
3744 break;
3745 /*=====================================================================*/
3746 case DRX_UIO3:
3747 /* DRX_UIO3: GPIO UIO-3 */
3748 if (extAttr->hasGPIO != TRUE)
3749 return DRX_STS_ERROR;
3750
3751 if (extAttr->uioGPIOMode != DRX_UIO_MODE_READWRITE) {
3752 return DRX_STS_ERROR;
3753 }
3754 pinCfgValue = 0;
3755 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3756 pinCfgValue |= 0x0110;
3757 /* io_pad_cfg_mode output mode is drive always */
3758 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3759
3760 /* write to io pad configuration register - input mode */
3761 WR16(demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, pinCfgValue);
3762
3763 /* read io input data registar */
3764 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_IN_HI__A, &value);
3765 if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
3766 UIOData->value = TRUE;
3767 } else {
3768 UIOData->value = FALSE;
3769 }
3770 break;
3771 /*=====================================================================*/
3772 case DRX_UIO4:
3773 /* DRX_UIO4: IRQN UIO-4 */
3774 if (extAttr->hasIRQN != TRUE)
3775 return DRX_STS_ERROR;
3776
3777 if (extAttr->uioIRQNMode != DRX_UIO_MODE_READWRITE) {
3778 return DRX_STS_ERROR;
3779 }
3780 pinCfgValue = 0;
3781 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3782 pinCfgValue |= 0x0110;
3783 /* io_pad_cfg_mode output mode is drive always */
3784 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3785
3786 /* write to io pad configuration register - input mode */
3787 WR16(demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, pinCfgValue);
3788
3789 /* read io input data registar */
3790 RR16(demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value);
3791 if ((value & 0x1000) != 0) { /* check 12th bit - 4th UIO */
3792 UIOData->value = TRUE;
3793 } else {
3794 UIOData->value = FALSE;
3795 }
3796 break;
3797 /*====================================================================*/
3798 default:
3799 return DRX_STS_INVALID_ARG;
3800 } /* switch ( UIOData->uio ) */
3801
3802 /* Write magic word to disable pdr reg write */
3803 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3804
3805 return (DRX_STS_OK);
3806 rw_error:
3807 return (DRX_STS_ERROR);
3808 }
3809
3810 /*---------------------------------------------------------------------------*/
3811 /* UIO Configuration Functions - end */
3812 /*---------------------------------------------------------------------------*/
3813
3814 /*----------------------------------------------------------------------------*/
3815 /* I2C Bridge Functions - begin */
3816 /*----------------------------------------------------------------------------*/
3817 /**
3818 * \fn DRXStatus_t CtrlI2CBridge()
3819 * \brief Open or close the I2C switch to tuner.
3820 * \param demod Pointer to demodulator instance.
3821 * \param bridgeClosed Pointer to bool indication if bridge is closed not.
3822 * \return DRXStatus_t.
3823
3824 */
3825 static DRXStatus_t
3826 CtrlI2CBridge(pDRXDemodInstance_t demod, pBool_t bridgeClosed)
3827 {
3828 DRXJHiCmd_t hiCmd;
3829 u16_t result = 0;
3830
3831 /* check arguments */
3832 if (bridgeClosed == NULL) {
3833 return (DRX_STS_INVALID_ARG);
3834 }
3835
3836 hiCmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3837 hiCmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3838 if (*bridgeClosed == TRUE) {
3839 hiCmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
3840 } else {
3841 hiCmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
3842 }
3843
3844 return HICommand(demod->myI2CDevAddr, &hiCmd, &result);
3845 }
3846
3847 /*----------------------------------------------------------------------------*/
3848 /* I2C Bridge Functions - end */
3849 /*----------------------------------------------------------------------------*/
3850
3851 /*----------------------------------------------------------------------------*/
3852 /* Smart antenna Functions - begin */
3853 /*----------------------------------------------------------------------------*/
3854 /**
3855 * \fn DRXStatus_t SmartAntInit()
3856 * \brief Initialize Smart Antenna.
3857 * \param pointer to DRXDemodInstance_t.
3858 * \return DRXStatus_t.
3859 *
3860 */
3861 static DRXStatus_t SmartAntInit(pDRXDemodInstance_t demod)
3862 {
3863 u16_t data = 0;
3864 pDRXJData_t extAttr = NULL;
3865 pI2CDeviceAddr_t devAddr = NULL;
3866 DRXUIOCfg_t UIOCfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
3867
3868 devAddr = demod->myI2CDevAddr;
3869 extAttr = (pDRXJData_t) demod->myExtAttr;
3870
3871 /* Write magic word to enable pdr reg write */
3872 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3873 /* init smart antenna */
3874 RR16(devAddr, SIO_SA_TX_COMMAND__A, &data);
3875 if (extAttr->smartAntInverted)
3876 WR16(devAddr, SIO_SA_TX_COMMAND__A,
3877 (data | SIO_SA_TX_COMMAND_TX_INVERT__M)
3878 | SIO_SA_TX_COMMAND_TX_ENABLE__M);
3879 else
3880 WR16(devAddr, SIO_SA_TX_COMMAND__A,
3881 (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M))
3882 | SIO_SA_TX_COMMAND_TX_ENABLE__M);
3883
3884 /* config SMA_TX pin to smart antenna mode */
3885 CHK_ERROR(CtrlSetUIOCfg(demod, &UIOCfg));
3886 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, 0x13);
3887 WR16(demod->myI2CDevAddr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03);
3888
3889 /* Write magic word to disable pdr reg write */
3890 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3891
3892 return (DRX_STS_OK);
3893 rw_error:
3894 return (DRX_STS_ERROR);
3895 }
3896
3897 /**
3898 * \fn DRXStatus_t CtrlSetCfgSmartAnt()
3899 * \brief Set Smart Antenna.
3900 * \param pointer to DRXJCfgSmartAnt_t.
3901 * \return DRXStatus_t.
3902 *
3903 */
3904 static DRXStatus_t
3905 CtrlSetCfgSmartAnt(pDRXDemodInstance_t demod, pDRXJCfgSmartAnt_t smartAnt)
3906 {
3907 pDRXJData_t extAttr = NULL;
3908 pI2CDeviceAddr_t devAddr = NULL;
3909 u16_t data = 0;
3910 u32_t startTime = 0;
3911 static Bool_t bitInverted = FALSE;
3912
3913 devAddr = demod->myI2CDevAddr;
3914 extAttr = (pDRXJData_t) demod->myExtAttr;
3915
3916 /* check arguments */
3917 if (smartAnt == NULL) {
3918 return (DRX_STS_INVALID_ARG);
3919 }
3920
3921 if (bitInverted != extAttr->smartAntInverted
3922 || extAttr->uioSmaTxMode != DRX_UIO_MODE_FIRMWARE_SMA) {
3923 CHK_ERROR(SmartAntInit(demod));
3924 bitInverted = extAttr->smartAntInverted;
3925 }
3926
3927 /* Write magic word to enable pdr reg write */
3928 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3929
3930 switch (smartAnt->io) {
3931 case DRXJ_SMT_ANT_OUTPUT:
3932 /* enable Tx if Mode B (input) is supported */
3933 /*
3934 RR16( devAddr, SIO_SA_TX_COMMAND__A, &data );
3935 WR16( devAddr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
3936 */
3937 startTime = DRXBSP_HST_Clock();
3938 do {
3939 RR16(devAddr, SIO_SA_TX_STATUS__A, &data);
3940 } while ((data & SIO_SA_TX_STATUS_BUSY__M)
3941 && ((DRXBSP_HST_Clock() - startTime) <
3942 DRXJ_MAX_WAITTIME));
3943
3944 if (data & SIO_SA_TX_STATUS_BUSY__M) {
3945 return (DRX_STS_ERROR);
3946 }
3947
3948 /* write to smart antenna configuration register */
3949 WR16(devAddr, SIO_SA_TX_DATA0__A, 0x9200
3950 | ((smartAnt->ctrlData & 0x0001) << 8)
3951 | ((smartAnt->ctrlData & 0x0002) << 10)
3952 | ((smartAnt->ctrlData & 0x0004) << 12)
3953 );
3954 WR16(devAddr, SIO_SA_TX_DATA1__A, 0x4924
3955 | ((smartAnt->ctrlData & 0x0008) >> 2)
3956 | ((smartAnt->ctrlData & 0x0010))
3957 | ((smartAnt->ctrlData & 0x0020) << 2)
3958 | ((smartAnt->ctrlData & 0x0040) << 4)
3959 | ((smartAnt->ctrlData & 0x0080) << 6)
3960 );
3961 WR16(devAddr, SIO_SA_TX_DATA2__A, 0x2492
3962 | ((smartAnt->ctrlData & 0x0100) >> 8)
3963 | ((smartAnt->ctrlData & 0x0200) >> 6)
3964 | ((smartAnt->ctrlData & 0x0400) >> 4)
3965 | ((smartAnt->ctrlData & 0x0800) >> 2)
3966 | ((smartAnt->ctrlData & 0x1000))
3967 | ((smartAnt->ctrlData & 0x2000) << 2)
3968 );
3969 WR16(devAddr, SIO_SA_TX_DATA3__A, 0xff8d);
3970
3971 /* trigger the sending */
3972 WR16(devAddr, SIO_SA_TX_LENGTH__A, 56);
3973
3974 break;
3975 case DRXJ_SMT_ANT_INPUT:
3976 /* disable Tx if Mode B (input) is supported */
3977 /*
3978 RR16( devAddr, SIO_SA_TX_COMMAND__A, &data );
3979 WR16( devAddr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
3980 */
3981 default:
3982 return (DRX_STS_INVALID_ARG);
3983 }
3984 /* Write magic word to enable pdr reg write */
3985 WR16(demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
3986
3987 return (DRX_STS_OK);
3988 rw_error:
3989 return (DRX_STS_ERROR);
3990 }
3991
3992 static DRXStatus_t SCUCommand(pI2CDeviceAddr_t devAddr, pDRXJSCUCmd_t cmd)
3993 {
3994 u16_t curCmd = 0;
3995 u32_t startTime = 0;
3996
3997 /* Check param */
3998 if (cmd == NULL)
3999 return (DRX_STS_INVALID_ARG);
4000
4001 /* Wait until SCU command interface is ready to receive command */
4002 RR16(devAddr, SCU_RAM_COMMAND__A, &curCmd);
4003 if (curCmd != DRX_SCU_READY) {
4004 return (DRX_STS_ERROR);
4005 }
4006
4007 switch (cmd->parameterLen) {
4008 case 5:
4009 WR16(devAddr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4)); /* fallthrough */
4010 case 4:
4011 WR16(devAddr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3)); /* fallthrough */
4012 case 3:
4013 WR16(devAddr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2)); /* fallthrough */
4014 case 2:
4015 WR16(devAddr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1)); /* fallthrough */
4016 case 1:
4017 WR16(devAddr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0)); /* fallthrough */
4018 case 0:
4019 /* do nothing */
4020 break;
4021 default:
4022 /* this number of parameters is not supported */
4023 return (DRX_STS_ERROR);
4024 }
4025 WR16(devAddr, SCU_RAM_COMMAND__A, cmd->command);
4026
4027 /* Wait until SCU has processed command */
4028 startTime = DRXBSP_HST_Clock();
4029 do {
4030 RR16(devAddr, SCU_RAM_COMMAND__A, &curCmd);
4031 } while (!(curCmd == DRX_SCU_READY)
4032 && ((DRXBSP_HST_Clock() - startTime) < DRXJ_MAX_WAITTIME));
4033
4034 if (curCmd != DRX_SCU_READY) {
4035 return (DRX_STS_ERROR);
4036 }
4037
4038 /* read results */
4039 if ((cmd->resultLen > 0) && (cmd->result != NULL)) {
4040 s16_t err;
4041
4042 switch (cmd->resultLen) {
4043 case 4:
4044 RR16(devAddr, SCU_RAM_PARAM_3__A, cmd->result + 3); /* fallthrough */
4045 case 3:
4046 RR16(devAddr, SCU_RAM_PARAM_2__A, cmd->result + 2); /* fallthrough */
4047 case 2:
4048 RR16(devAddr, SCU_RAM_PARAM_1__A, cmd->result + 1); /* fallthrough */
4049 case 1:
4050 RR16(devAddr, SCU_RAM_PARAM_0__A, cmd->result + 0); /* fallthrough */
4051 case 0:
4052 /* do nothing */
4053 break;
4054 default:
4055 /* this number of parameters is not supported */
4056 return (DRX_STS_ERROR);
4057 }
4058
4059 /* Check if an error was reported by SCU */
4060 err = cmd->result[0];
4061
4062 /* check a few fixed error codes */
4063 if ((err == (s16_t) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4064 || (err == (s16_t) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4065 || (err == (s16_t) SCU_RAM_PARAM_0_RESULT_INVPAR)
4066 || (err == (s16_t) SCU_RAM_PARAM_0_RESULT_SIZE)
4067 ) {
4068 return DRX_STS_INVALID_ARG;
4069 }
4070 /* here it is assumed that negative means error, and positive no error */
4071 else if (err < 0) {
4072 return DRX_STS_ERROR;
4073 } else {
4074 return DRX_STS_OK;
4075 }
4076 }
4077
4078 return (DRX_STS_OK);
4079
4080 rw_error:
4081 return (DRX_STS_ERROR);
4082 }
4083
4084 /**
4085 * \fn DRXStatus_t DRXJ_DAP_SCUAtomicReadWriteBlock()
4086 * \brief Basic access routine for SCU atomic read or write access
4087 * \param devAddr pointer to i2c dev address
4088 * \param addr destination/source address
4089 * \param datasize size of data buffer in bytes
4090 * \param data pointer to data buffer
4091 * \return DRXStatus_t
4092 * \retval DRX_STS_OK Succes
4093 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
4094 *
4095 */
4096 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4097 static
4098 DRXStatus_t DRXJ_DAP_SCU_AtomicReadWriteBlock(pI2CDeviceAddr_t devAddr, DRXaddr_t addr, u16_t datasize, /* max 30 bytes because the limit of SCU parameter */
4099 pu8_t data, Bool_t readFlag)
4100 {
4101 DRXJSCUCmd_t scuCmd;
4102 u16_t setParamParameters[15];
4103 u16_t cmdResult[15];
4104
4105 /* Parameter check */
4106 if ((data == NULL) ||
4107 (devAddr == NULL) || ((datasize % 2) != 0) || ((datasize / 2) > 16)
4108 ) {
4109 return (DRX_STS_INVALID_ARG);
4110 }
4111
4112 setParamParameters[1] = (u16_t) ADDR_AT_SCU_SPACE(addr);
4113 if (readFlag) { /* read */
4114 setParamParameters[0] = ((~(0x0080)) & datasize);
4115 scuCmd.parameterLen = 2;
4116 scuCmd.resultLen = datasize / 2 + 2;
4117 } else {
4118 int i = 0;
4119
4120 setParamParameters[0] = 0x0080 | datasize;
4121 for (i = 0; i < (datasize / 2); i++) {
4122 setParamParameters[i + 2] =
4123 (data[2 * i] | (data[(2 * i) + 1] << 8));
4124 }
4125 scuCmd.parameterLen = datasize / 2 + 2;
4126 scuCmd.resultLen = 1;
4127 }
4128
4129 scuCmd.command =
4130 SCU_RAM_COMMAND_STANDARD_TOP |
4131 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4132 scuCmd.result = cmdResult;
4133 scuCmd.parameter = setParamParameters;
4134 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
4135
4136 if (readFlag == TRUE) {
4137 int i = 0;
4138 /* read data from buffer */
4139 for (i = 0; i < (datasize / 2); i++) {
4140 data[2 * i] = (u8_t) (scuCmd.result[i + 2] & 0xFF);
4141 data[(2 * i) + 1] = (u8_t) (scuCmd.result[i + 2] >> 8);
4142 }
4143 }
4144
4145 return DRX_STS_OK;
4146
4147 rw_error:
4148 return (DRX_STS_ERROR);
4149
4150 }
4151
4152 /*============================================================================*/
4153
4154 /**
4155 * \fn DRXStatus_t DRXJ_DAP_AtomicReadReg16()
4156 * \brief Atomic read of 16 bits words
4157 */
4158 static
4159 DRXStatus_t DRXJ_DAP_SCU_AtomicReadReg16(pI2CDeviceAddr_t devAddr,
4160 DRXaddr_t addr,
4161 pu16_t data, DRXflags_t flags)
4162 {
4163 u8_t buf[2];
4164 DRXStatus_t rc = DRX_STS_ERROR;
4165 u16_t word = 0;
4166
4167 if (!data) {
4168 return DRX_STS_INVALID_ARG;
4169 }
4170
4171 rc = DRXJ_DAP_SCU_AtomicReadWriteBlock(devAddr, addr, 2, buf, TRUE);
4172
4173 word = (u16_t) (buf[0] + (buf[1] << 8));
4174
4175 *data = word;
4176
4177 return rc;
4178 }
4179
4180 /*============================================================================*/
4181 /**
4182 * \fn DRXStatus_t DRXJ_DAP_SCU_AtomicWriteReg16()
4183 * \brief Atomic read of 16 bits words
4184 */
4185 static
4186 DRXStatus_t DRXJ_DAP_SCU_AtomicWriteReg16(pI2CDeviceAddr_t devAddr,
4187 DRXaddr_t addr,
4188 u16_t data, DRXflags_t flags)
4189 {
4190 u8_t buf[2];
4191 DRXStatus_t rc = DRX_STS_ERROR;
4192
4193 buf[0] = (u8_t) (data & 0xff);
4194 buf[1] = (u8_t) ((data >> 8) & 0xff);
4195
4196 rc = DRXJ_DAP_SCU_AtomicReadWriteBlock(devAddr, addr, 2, buf, FALSE);
4197
4198 return rc;
4199 }
4200
4201 static DRXStatus_t
4202 CtrlI2CWriteRead(pDRXDemodInstance_t demod, pDRXI2CData_t i2cData)
4203 {
4204 return (DRX_STS_FUNC_NOT_AVAILABLE);
4205 }
4206
4207 DRXStatus_t
4208 TunerI2CWriteRead(pTUNERInstance_t tuner,
4209 pI2CDeviceAddr_t wDevAddr,
4210 u16_t wCount,
4211 pu8_t wData,
4212 pI2CDeviceAddr_t rDevAddr, u16_t rCount, pu8_t rData)
4213 {
4214 pDRXDemodInstance_t demod;
4215 DRXI2CData_t i2cData =
4216 { 2, wDevAddr, wCount, wData, rDevAddr, rCount, rData };
4217
4218 demod = (pDRXDemodInstance_t) (tuner->myCommonAttr->myUserData);
4219
4220 return (CtrlI2CWriteRead(demod, &i2cData));
4221 }
4222
4223 /* -------------------------------------------------------------------------- */
4224 /**
4225 * \brief Measure result of ADC synchronisation
4226 * \param demod demod instance
4227 * \param count (returned) count
4228 * \return DRXStatus_t.
4229 * \retval DRX_STS_OK Success
4230 * \retval DRX_STS_ERROR Failure: I2C error
4231 *
4232 */
4233 static DRXStatus_t ADCSyncMeasurement(pDRXDemodInstance_t demod, pu16_t count)
4234 {
4235 u16_t data = 0;
4236 pI2CDeviceAddr_t devAddr = NULL;
4237
4238 devAddr = demod->myI2CDevAddr;
4239
4240 /* Start measurement */
4241 WR16(devAddr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
4242 WR16(devAddr, IQM_AF_START_LOCK__A, 1);
4243
4244 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4245 CHK_ERROR(DRXBSP_HST_Sleep(1));
4246
4247 *count = 0;
4248 RR16(devAddr, IQM_AF_PHASE0__A, &data);
4249 if (data == 127) {
4250 *count = *count + 1;
4251 }
4252 RR16(devAddr, IQM_AF_PHASE1__A, &data);
4253 if (data == 127) {
4254 *count = *count + 1;
4255 }
4256 RR16(devAddr, IQM_AF_PHASE2__A, &data);
4257 if (data == 127) {
4258 *count = *count + 1;
4259 }
4260
4261 return (DRX_STS_OK);
4262 rw_error:
4263 return (DRX_STS_ERROR);
4264 }
4265
4266 /**
4267 * \brief Synchronize analog and digital clock domains
4268 * \param demod demod instance
4269 * \return DRXStatus_t.
4270 * \retval DRX_STS_OK Success
4271 * \retval DRX_STS_ERROR Failure: I2C error or failure to synchronize
4272 *
4273 * An IQM reset will also reset the results of this synchronization.
4274 * After an IQM reset this routine needs to be called again.
4275 *
4276 */
4277
4278 static DRXStatus_t ADCSynchronization(pDRXDemodInstance_t demod)
4279 {
4280 u16_t count = 0;
4281 pI2CDeviceAddr_t devAddr = NULL;
4282
4283 devAddr = demod->myI2CDevAddr;
4284
4285 CHK_ERROR(ADCSyncMeasurement(demod, &count));
4286
4287 if (count == 1) {
4288 /* Try sampling on a diffrent edge */
4289 u16_t clkNeg = 0;
4290
4291 RR16(devAddr, IQM_AF_CLKNEG__A, &clkNeg);
4292
4293 clkNeg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4294 WR16(devAddr, IQM_AF_CLKNEG__A, clkNeg);
4295
4296 CHK_ERROR(ADCSyncMeasurement(demod, &count));
4297 }
4298
4299 if (count < 2) {
4300 /* TODO: implement fallback scenarios */
4301 return (DRX_STS_ERROR);
4302 }
4303
4304 return (DRX_STS_OK);
4305 rw_error:
4306 return (DRX_STS_ERROR);
4307 }
4308
4309 /**
4310 * \brief Configure IQM AF registers
4311 * \param demod instance of demodulator.
4312 * \param active
4313 * \return DRXStatus_t.
4314 */
4315 static DRXStatus_t IQMSetAf(pDRXDemodInstance_t demod, Bool_t active)
4316 {
4317 u16_t data = 0;
4318 pI2CDeviceAddr_t devAddr = NULL;
4319 pDRXJData_t extAttr = NULL;
4320
4321 extAttr = (pDRXJData_t) demod->myExtAttr;
4322 devAddr = demod->myI2CDevAddr;
4323
4324 /* Configure IQM */
4325 RR16(devAddr, IQM_AF_STDBY__A, &data);
4326 if (!active) {
4327 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
4328 & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
4329 & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
4330 & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
4331 & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
4332 );
4333 } else { /* active */
4334
4335 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
4336 | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
4337 | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
4338 | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
4339 | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
4340 }
4341 WR16(devAddr, IQM_AF_STDBY__A, data);
4342
4343 return (DRX_STS_OK);
4344 rw_error:
4345 return (DRX_STS_ERROR);
4346 }
4347
4348 /* -------------------------------------------------------------------------- */
4349 static DRXStatus_t
4350 CtrlSetCfgATVOutput(pDRXDemodInstance_t demod, pDRXJCfgAtvOutput_t outputCfg);
4351
4352 /**
4353 * \brief set configuration of pin-safe mode
4354 * \param demod instance of demodulator.
4355 * \param enable boolean; TRUE: activate pin-safe mode, FALSE: de-activate p.s.m.
4356 * \return DRXStatus_t.
4357 */
4358 static DRXStatus_t
4359 CtrlSetCfgPdrSafeMode(pDRXDemodInstance_t demod, pBool_t enable)
4360 {
4361 pDRXJData_t extAttr = (pDRXJData_t) NULL;
4362 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
4363 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) NULL;
4364
4365 if (enable == NULL) {
4366 return (DRX_STS_INVALID_ARG);
4367 }
4368
4369 devAddr = demod->myI2CDevAddr;
4370 extAttr = (pDRXJData_t) demod->myExtAttr;
4371 commonAttr = demod->myCommonAttr;
4372
4373 /* Write magic word to enable pdr reg write */
4374 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
4375
4376 if (*enable == TRUE) {
4377 Bool_t bridgeEnabled = FALSE;
4378
4379 /* MPEG pins to input */
4380 WR16(devAddr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE);
4381 WR16(devAddr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE);
4382 WR16(devAddr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE);
4383 WR16(devAddr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE);
4384 WR16(devAddr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE);
4385 WR16(devAddr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE);
4386 WR16(devAddr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE);
4387 WR16(devAddr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE);
4388 WR16(devAddr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE);
4389 WR16(devAddr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE);
4390 WR16(devAddr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE);
4391 WR16(devAddr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE);
4392
4393 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
4394 PD_I2C_SCL2 Bridge off, Port2 Inactive */
4395 CHK_ERROR(CtrlI2CBridge(demod, &bridgeEnabled));
4396 WR16(devAddr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE);
4397 WR16(devAddr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE);
4398
4399 /* PD_GPIO Store and set to input
4400 PD_VSYNC Store and set to input
4401 PD_SMA_RX Store and set to input
4402 PD_SMA_TX Store and set to input */
4403 RR16(devAddr, SIO_PDR_GPIO_CFG__A,
4404 &extAttr->pdrSafeRestoreValGpio);
4405 RR16(devAddr, SIO_PDR_VSYNC_CFG__A,
4406 &extAttr->pdrSafeRestoreValVSync);
4407 RR16(devAddr, SIO_PDR_SMA_RX_CFG__A,
4408 &extAttr->pdrSafeRestoreValSmaRx);
4409 RR16(devAddr, SIO_PDR_SMA_TX_CFG__A,
4410 &extAttr->pdrSafeRestoreValSmaTx);
4411 WR16(devAddr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE);
4412 WR16(devAddr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE);
4413 WR16(devAddr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE);
4414 WR16(devAddr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE);
4415
4416 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
4417 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
4418 CHK_ERROR(IQMSetAf(demod, FALSE));
4419
4420 /* PD_CVBS Analog DAC output, standby mode
4421 PD_SIF Analog DAC output, standby mode */
4422 WR16(devAddr, ATV_TOP_STDBY__A,
4423 (ATV_TOP_STDBY_SIF_STDBY_STANDBY &
4424 (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)));
4425
4426 /* PD_I2S_CL Input
4427 PD_I2S_DA Input
4428 PD_I2S_WS Input */
4429 WR16(devAddr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE);
4430 WR16(devAddr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE);
4431 WR16(devAddr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE);
4432 } else {
4433 /* No need to restore MPEG pins;
4434 is done in SetStandard/SetChannel */
4435
4436 /* PD_I2C_SDA2 Port2 active
4437 PD_I2C_SCL2 Port2 active */
4438 WR16(devAddr, SIO_PDR_I2C_SDA2_CFG__A,
4439 SIO_PDR_I2C_SDA2_CFG__PRE);
4440 WR16(devAddr, SIO_PDR_I2C_SCL2_CFG__A,
4441 SIO_PDR_I2C_SCL2_CFG__PRE);
4442
4443 /* PD_GPIO Restore
4444 PD_VSYNC Restore
4445 PD_SMA_RX Restore
4446 PD_SMA_TX Restore */
4447 WR16(devAddr, SIO_PDR_GPIO_CFG__A,
4448 extAttr->pdrSafeRestoreValGpio);
4449 WR16(devAddr, SIO_PDR_VSYNC_CFG__A,
4450 extAttr->pdrSafeRestoreValVSync);
4451 WR16(devAddr, SIO_PDR_SMA_RX_CFG__A,
4452 extAttr->pdrSafeRestoreValSmaRx);
4453 WR16(devAddr, SIO_PDR_SMA_TX_CFG__A,
4454 extAttr->pdrSafeRestoreValSmaTx);
4455
4456 /* PD_RF_AGC, PD_IF_AGC
4457 No need to restore; will be restored in SetStandard/SetChannel */
4458
4459 /* PD_CVBS, PD_SIF
4460 No need to restore; will be restored in SetStandard/SetChannel */
4461
4462 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
4463 Should be restored via DRX_CTRL_SET_AUD */
4464 }
4465
4466 /* Write magic word to disable pdr reg write */
4467 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0x0000);
4468 extAttr->pdrSafeMode = *enable;
4469
4470 return (DRX_STS_OK);
4471
4472 rw_error:
4473 return (DRX_STS_ERROR);
4474 }
4475
4476 /* -------------------------------------------------------------------------- */
4477
4478 /**
4479 * \brief get configuration of pin-safe mode
4480 * \param demod instance of demodulator.
4481 * \param enable boolean indicating whether pin-safe mode is active
4482 * \return DRXStatus_t.
4483 */
4484 static DRXStatus_t
4485 CtrlGetCfgPdrSafeMode(pDRXDemodInstance_t demod, pBool_t enabled)
4486 {
4487 pDRXJData_t extAttr = (pDRXJData_t) NULL;
4488
4489 if (enabled == NULL) {
4490 return (DRX_STS_INVALID_ARG);
4491 }
4492
4493 extAttr = (pDRXJData_t) demod->myExtAttr;
4494 *enabled = extAttr->pdrSafeMode;
4495
4496 return (DRX_STS_OK);
4497 }
4498
4499 /**
4500 * \brief Verifies whether microcode can be loaded.
4501 * \param demod Demodulator instance.
4502 * \return DRXStatus_t.
4503 */
4504 static DRXStatus_t CtrlValidateUCode(pDRXDemodInstance_t demod)
4505 {
4506 u32_t mcDev, mcPatch;
4507 u16_t verType;
4508
4509 /* Check device.
4510 * Disallow microcode if:
4511 * - MC has version record AND
4512 * - device ID in version record is not 0 AND
4513 * - product ID in version record's device ID does not
4514 * match DRXJ1 product IDs - 0x393 or 0x394
4515 */
4516 DRX_GET_MCVERTYPE(demod, verType);
4517 DRX_GET_MCDEV(demod, mcDev);
4518 DRX_GET_MCPATCH(demod, mcPatch);
4519
4520 if (DRX_ISMCVERTYPE(verType)) {
4521 if ((mcDev != 0) &&
4522 (((mcDev >> 16) & 0xFFF) != 0x393) &&
4523 (((mcDev >> 16) & 0xFFF) != 0x394)) {
4524 /* Microcode is marked for another device - error */
4525 return DRX_STS_INVALID_ARG;
4526 } else if (mcPatch != 0) {
4527 /* Patch not allowed because there is no ROM */
4528 return DRX_STS_INVALID_ARG;
4529 }
4530 }
4531
4532 /* Everything else: OK */
4533 return DRX_STS_OK;
4534 }
4535
4536 /*============================================================================*/
4537 /*== END AUXILIARY FUNCTIONS ==*/
4538 /*============================================================================*/
4539
4540 /*============================================================================*/
4541 /*============================================================================*/
4542 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4543 /*============================================================================*/
4544 /*============================================================================*/
4545 /**
4546 * \fn DRXStatus_t InitAGC ()
4547 * \brief Initialize AGC for all standards.
4548 * \param demod instance of demodulator.
4549 * \param channel pointer to channel data.
4550 * \return DRXStatus_t.
4551 */
4552 static DRXStatus_t InitAGC(pDRXDemodInstance_t demod)
4553 {
4554 pI2CDeviceAddr_t devAddr = NULL;
4555 pDRXCommonAttr_t commonAttr = NULL;
4556 pDRXJData_t extAttr = NULL;
4557 pDRXJCfgAgc_t pAgcRfSettings = NULL;
4558 pDRXJCfgAgc_t pAgcIfSettings = NULL;
4559 u16_t IngainTgtMax = 0;
4560 u16_t clpDirTo = 0;
4561 u16_t snsSumMax = 0;
4562 u16_t clpSumMax = 0;
4563 u16_t snsDirTo = 0;
4564 u16_t kiInnergainMin = 0;
4565 u16_t agcKi = 0;
4566 u16_t kiMax = 0;
4567 u16_t ifIaccuHiTgtMin = 0;
4568 u16_t data = 0;
4569 u16_t agcKiDgain = 0;
4570 u16_t kiMin = 0;
4571 u16_t clpCtrlMode = 0;
4572 u16_t agcRf = 0;
4573 u16_t agcIf = 0;
4574 devAddr = demod->myI2CDevAddr;
4575 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
4576 extAttr = (pDRXJData_t) demod->myExtAttr;
4577
4578 switch (extAttr->standard) {
4579 case DRX_STANDARD_8VSB:
4580 clpSumMax = 1023;
4581 clpDirTo = (u16_t) (-9);
4582 snsSumMax = 1023;
4583 snsDirTo = (u16_t) (-9);
4584 kiInnergainMin = (u16_t) (-32768);
4585 kiMax = 0x032C;
4586 agcKiDgain = 0xC;
4587 ifIaccuHiTgtMin = 2047;
4588 kiMin = 0x0117;
4589 IngainTgtMax = 16383;
4590 clpCtrlMode = 0;
4591 WR16(devAddr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
4592 WR16(devAddr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
4593 WR16(devAddr, SCU_RAM_AGC_CLP_SUM__A, 0);
4594 WR16(devAddr, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
4595 WR16(devAddr, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
4596 WR16(devAddr, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
4597 WR16(devAddr, SCU_RAM_AGC_SNS_SUM__A, 0);
4598 WR16(devAddr, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
4599 WR16(devAddr, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
4600 WR16(devAddr, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
4601 WR16(devAddr, SCU_RAM_AGC_INGAIN__A, 1024);
4602 WR16(devAddr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600);
4603 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT__A, 13200);
4604 pAgcIfSettings = &(extAttr->vsbIfAgcCfg);
4605 pAgcRfSettings = &(extAttr->vsbRfAgcCfg);
4606 break;
4607 #ifndef DRXJ_VSB_ONLY
4608 case DRX_STANDARD_ITU_A:
4609 case DRX_STANDARD_ITU_C:
4610 case DRX_STANDARD_ITU_B:
4611 IngainTgtMax = 5119;
4612 clpSumMax = 1023;
4613 clpDirTo = (u16_t) (-5);
4614 snsSumMax = 127;
4615 snsDirTo = (u16_t) (-3);
4616 kiInnergainMin = 0;
4617 kiMax = 0x0657;
4618 ifIaccuHiTgtMin = 2047;
4619 agcKiDgain = 0x7;
4620 kiMin = 0x0117;
4621 clpCtrlMode = 0;
4622 WR16(devAddr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
4623 WR16(devAddr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
4624 WR16(devAddr, SCU_RAM_AGC_CLP_SUM__A, 0);
4625 WR16(devAddr, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
4626 WR16(devAddr, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
4627 WR16(devAddr, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
4628 WR16(devAddr, SCU_RAM_AGC_SNS_SUM__A, 0);
4629 WR16(devAddr, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
4630 WR16(devAddr, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
4631 WR16(devAddr, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
4632 pAgcIfSettings = &(extAttr->qamIfAgcCfg);
4633 pAgcRfSettings = &(extAttr->qamRfAgcCfg);
4634 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top);
4635
4636 RR16(devAddr, SCU_RAM_AGC_KI__A, &agcKi);
4637 agcKi &= 0xf000;
4638 WR16(devAddr, SCU_RAM_AGC_KI__A, agcKi);
4639 break;
4640 #endif
4641 #ifndef DRXJ_DIGITAL_ONLY
4642 case DRX_STANDARD_FM:
4643 clpSumMax = 1023;
4644 snsSumMax = 1023;
4645 kiInnergainMin = (u16_t) (-32768);
4646 ifIaccuHiTgtMin = 2047;
4647 agcKiDgain = 0x7;
4648 kiMin = 0x0225;
4649 kiMax = 0x0547;
4650 clpDirTo = (u16_t) (-9);
4651 snsDirTo = (u16_t) (-9);
4652 IngainTgtMax = 9000;
4653 clpCtrlMode = 1;
4654 pAgcIfSettings = &(extAttr->atvIfAgcCfg);
4655 pAgcRfSettings = &(extAttr->atvRfAgcCfg);
4656 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top);
4657 break;
4658 case DRX_STANDARD_NTSC:
4659 case DRX_STANDARD_PAL_SECAM_BG:
4660 case DRX_STANDARD_PAL_SECAM_DK:
4661 case DRX_STANDARD_PAL_SECAM_I:
4662 clpSumMax = 1023;
4663 snsSumMax = 1023;
4664 kiInnergainMin = (u16_t) (-32768);
4665 ifIaccuHiTgtMin = 2047;
4666 agcKiDgain = 0x7;
4667 kiMin = 0x0225;
4668 kiMax = 0x0547;
4669 clpDirTo = (u16_t) (-9);
4670 IngainTgtMax = 9000;
4671 pAgcIfSettings = &(extAttr->atvIfAgcCfg);
4672 pAgcRfSettings = &(extAttr->atvRfAgcCfg);
4673 snsDirTo = (u16_t) (-9);
4674 clpCtrlMode = 1;
4675 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top);
4676 break;
4677 case DRX_STANDARD_PAL_SECAM_L:
4678 case DRX_STANDARD_PAL_SECAM_LP:
4679 clpSumMax = 1023;
4680 snsSumMax = 1023;
4681 kiInnergainMin = (u16_t) (-32768);
4682 ifIaccuHiTgtMin = 2047;
4683 agcKiDgain = 0x7;
4684 kiMin = 0x0225;
4685 kiMax = 0x0547;
4686 clpDirTo = (u16_t) (-9);
4687 snsDirTo = (u16_t) (-9);
4688 IngainTgtMax = 9000;
4689 clpCtrlMode = 1;
4690 pAgcIfSettings = &(extAttr->atvIfAgcCfg);
4691 pAgcRfSettings = &(extAttr->atvRfAgcCfg);
4692 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top);
4693 break;
4694 #endif
4695 default:
4696 return (DRX_STS_INVALID_ARG);
4697 }
4698
4699 /* for new AGC interface */
4700 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcIfSettings->top);
4701 WR16(devAddr, SCU_RAM_AGC_INGAIN__A, pAgcIfSettings->top); /* Gain fed from inner to outer AGC */
4702 WR16(devAddr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, IngainTgtMax);
4703 WR16(devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
4704 WR16(devAddr, SCU_RAM_AGC_IF_IACCU_HI__A, 0); /* set to pAgcSettings->top before */
4705 WR16(devAddr, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
4706 WR16(devAddr, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
4707 WR16(devAddr, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
4708 WR16(devAddr, SCU_RAM_AGC_RF_MAX__A, 32767);
4709 WR16(devAddr, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
4710 WR16(devAddr, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
4711 WR16(devAddr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
4712 WR16(devAddr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
4713 WR16(devAddr, SCU_RAM_AGC_KI_CYCLEN__A, 500);
4714 WR16(devAddr, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
4715 WR16(devAddr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
4716 WR16(devAddr, SCU_RAM_AGC_KI_MIN__A, kiMin);
4717 WR16(devAddr, SCU_RAM_AGC_KI_MAX__A, kiMax);
4718 WR16(devAddr, SCU_RAM_AGC_KI_RED__A, 0);
4719 WR16(devAddr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8);
4720 WR16(devAddr, SCU_RAM_AGC_CLP_CYCLEN__A, 500);
4721 WR16(devAddr, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
4722 WR16(devAddr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8);
4723 WR16(devAddr, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
4724 WR16(devAddr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50);
4725 WR16(devAddr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
4726
4727 agcRf = 0x800 + pAgcRfSettings->cutOffCurrent;
4728 if (commonAttr->tunerRfAgcPol == TRUE) {
4729 agcRf = 0x87ff - agcRf;
4730 }
4731
4732 agcIf = 0x800;
4733 if (commonAttr->tunerIfAgcPol == TRUE) {
4734 agcRf = 0x87ff - agcRf;
4735 }
4736
4737 WR16(devAddr, IQM_AF_AGC_RF__A, agcRf);
4738 WR16(devAddr, IQM_AF_AGC_IF__A, agcIf);
4739
4740 /* Set/restore Ki DGAIN factor */
4741 RR16(devAddr, SCU_RAM_AGC_KI__A, &data);
4742 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
4743 data |= (agcKiDgain << SCU_RAM_AGC_KI_DGAIN__B);
4744 WR16(devAddr, SCU_RAM_AGC_KI__A, data);
4745
4746 return (DRX_STS_OK);
4747 rw_error:
4748 return (DRX_STS_ERROR);
4749 }
4750
4751 /**
4752 * \fn DRXStatus_t SetFrequency ()
4753 * \brief Set frequency shift.
4754 * \param demod instance of demodulator.
4755 * \param channel pointer to channel data.
4756 * \param tunerFreqOffset residual frequency from tuner.
4757 * \return DRXStatus_t.
4758 */
4759 static DRXStatus_t
4760 SetFrequency(pDRXDemodInstance_t demod,
4761 pDRXChannel_t channel, DRXFrequency_t tunerFreqOffset)
4762 {
4763 pI2CDeviceAddr_t devAddr = NULL;
4764 pDRXCommonAttr_t commonAttr = NULL;
4765 DRXFrequency_t samplingFrequency = 0;
4766 DRXFrequency_t frequencyShift = 0;
4767 DRXFrequency_t ifFreqActual = 0;
4768 DRXFrequency_t rfFreqResidual = 0;
4769 DRXFrequency_t adcFreq = 0;
4770 DRXFrequency_t intermediateFreq = 0;
4771 u32_t iqmFsRateOfs = 0;
4772 pDRXJData_t extAttr = NULL;
4773 Bool_t adcFlip = TRUE;
4774 Bool_t selectPosImage = FALSE;
4775 Bool_t rfMirror = FALSE;
4776 Bool_t tunerMirror = TRUE;
4777 Bool_t imageToSelect = TRUE;
4778 DRXFrequency_t fmFrequencyShift = 0;
4779
4780 devAddr = demod->myI2CDevAddr;
4781 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
4782 extAttr = (pDRXJData_t) demod->myExtAttr;
4783 rfFreqResidual = -1 * tunerFreqOffset;
4784 rfMirror = (extAttr->mirror == DRX_MIRROR_YES) ? TRUE : FALSE;
4785 tunerMirror = demod->myCommonAttr->mirrorFreqSpect ? FALSE : TRUE;
4786 /*
4787 Program frequency shifter
4788 No need to account for mirroring on RF
4789 */
4790 switch (extAttr->standard) {
4791 case DRX_STANDARD_ITU_A: /* fallthrough */
4792 case DRX_STANDARD_ITU_C: /* fallthrough */
4793 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
4794 case DRX_STANDARD_8VSB:
4795 selectPosImage = TRUE;
4796 break;
4797 case DRX_STANDARD_FM:
4798 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4799 Sound carrier is already 3Mhz above centre frequency due
4800 to tuner setting so now add an extra shift of 1MHz... */
4801 fmFrequencyShift = 1000;
4802 case DRX_STANDARD_ITU_B: /* fallthrough */
4803 case DRX_STANDARD_NTSC: /* fallthrough */
4804 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
4805 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
4806 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
4807 case DRX_STANDARD_PAL_SECAM_L:
4808 selectPosImage = FALSE;
4809 break;
4810 default:
4811 return (DRX_STS_INVALID_ARG);
4812 }
4813 intermediateFreq = demod->myCommonAttr->intermediateFreq;
4814 samplingFrequency = demod->myCommonAttr->sysClockFreq / 3;
4815 if (tunerMirror == TRUE) {
4816 /* tuner doesn't mirror */
4817 ifFreqActual =
4818 intermediateFreq + rfFreqResidual + fmFrequencyShift;
4819 } else {
4820 /* tuner mirrors */
4821 ifFreqActual =
4822 intermediateFreq - rfFreqResidual - fmFrequencyShift;
4823 }
4824 if (ifFreqActual > samplingFrequency / 2) {
4825 /* adc mirrors */
4826 adcFreq = samplingFrequency - ifFreqActual;
4827 adcFlip = TRUE;
4828 } else {
4829 /* adc doesn't mirror */
4830 adcFreq = ifFreqActual;
4831 adcFlip = FALSE;
4832 }
4833
4834 frequencyShift = adcFreq;
4835 imageToSelect =
4836 (Bool_t) (rfMirror ^ tunerMirror ^ adcFlip ^ selectPosImage);
4837 iqmFsRateOfs = Frac28(frequencyShift, samplingFrequency);
4838
4839 if (imageToSelect)
4840 iqmFsRateOfs = ~iqmFsRateOfs + 1;
4841
4842 /* Program frequency shifter with tuner offset compensation */
4843 /* frequencyShift += tunerFreqOffset; TODO */
4844 WR32(devAddr, IQM_FS_RATE_OFS_LO__A, iqmFsRateOfs);
4845 extAttr->iqmFsRateOfs = iqmFsRateOfs;
4846 extAttr->posImage = (Bool_t) (rfMirror ^ tunerMirror ^ selectPosImage);
4847
4848 return (DRX_STS_OK);
4849 rw_error:
4850 return (DRX_STS_ERROR);
4851 }
4852
4853 /**
4854 * \fn DRXStatus_t GetSigStrength()
4855 * \brief Retrieve signal strength for VSB and QAM.
4856 * \param demod Pointer to demod instance
4857 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
4858 * \return DRXStatus_t.
4859 * \retval DRX_STS_OK sigStrength contains valid data.
4860 * \retval DRX_STS_INVALID_ARG sigStrength is NULL.
4861 * \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
4862 */
4863 #define DRXJ_AGC_TOP 0x2800
4864 #define DRXJ_AGC_SNS 0x1600
4865 #define DRXJ_RFAGC_MAX 0x3fff
4866 #define DRXJ_RFAGC_MIN 0x800
4867
4868 static DRXStatus_t GetSigStrength(pDRXDemodInstance_t demod, pu16_t sigStrength)
4869 {
4870 u16_t rfGain = 0;
4871 u16_t ifGain = 0;
4872 u16_t ifAgcSns = 0;
4873 u16_t ifAgcTop = 0;
4874 u16_t rfAgcMax = 0;
4875 u16_t rfAgcMin = 0;
4876 pDRXJData_t extAttr = NULL;
4877 pI2CDeviceAddr_t devAddr = NULL;
4878
4879 extAttr = (pDRXJData_t) demod->myExtAttr;
4880 devAddr = demod->myI2CDevAddr;
4881
4882 RR16(devAddr, IQM_AF_AGC_IF__A, &ifGain);
4883 ifGain &= IQM_AF_AGC_IF__M;
4884 RR16(devAddr, IQM_AF_AGC_RF__A, &rfGain);
4885 rfGain &= IQM_AF_AGC_RF__M;
4886
4887 ifAgcSns = DRXJ_AGC_SNS;
4888 ifAgcTop = DRXJ_AGC_TOP;
4889 rfAgcMax = DRXJ_RFAGC_MAX;
4890 rfAgcMin = DRXJ_RFAGC_MIN;
4891
4892 if (ifGain > ifAgcTop) {
4893 if (rfGain > rfAgcMax)
4894 *sigStrength = 100;
4895 else if (rfGain > rfAgcMin) {
4896 CHK_ZERO(rfAgcMax - rfAgcMin);
4897 *sigStrength =
4898 75 + 25 * (rfGain - rfAgcMin) / (rfAgcMax -
4899 rfAgcMin);
4900 } else
4901 *sigStrength = 75;
4902 } else if (ifGain > ifAgcSns) {
4903 CHK_ZERO(ifAgcTop - ifAgcSns);
4904 *sigStrength =
4905 20 + 55 * (ifGain - ifAgcSns) / (ifAgcTop - ifAgcSns);
4906 } else {
4907 CHK_ZERO(ifAgcSns);
4908 *sigStrength = (20 * ifGain / ifAgcSns);
4909 }
4910
4911 return (DRX_STS_OK);
4912 rw_error:
4913 return (DRX_STS_ERROR);
4914 }
4915
4916 /**
4917 * \fn DRXStatus_t GetAccPktErr()
4918 * \brief Retrieve signal strength for VSB and QAM.
4919 * \param demod Pointer to demod instance
4920 * \param packetErr Pointer to packet error
4921 * \return DRXStatus_t.
4922 * \retval DRX_STS_OK sigStrength contains valid data.
4923 * \retval DRX_STS_INVALID_ARG sigStrength is NULL.
4924 * \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
4925 */
4926 #ifdef DRXJ_SIGNAL_ACCUM_ERR
4927 static DRXStatus_t GetAccPktErr(pDRXDemodInstance_t demod, pu16_t packetErr)
4928 {
4929 static u16_t pktErr = 0;
4930 static u16_t lastPktErr = 0;
4931 u16_t data = 0;
4932 pDRXJData_t extAttr = NULL;
4933 pI2CDeviceAddr_t devAddr = NULL;
4934
4935 extAttr = (pDRXJData_t) demod->myExtAttr;
4936 devAddr = demod->myI2CDevAddr;
4937
4938 RR16(devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data);
4939 if (extAttr->resetPktErrAcc == TRUE) {
4940 lastPktErr = data;
4941 pktErr = 0;
4942 extAttr->resetPktErrAcc = FALSE;
4943 }
4944
4945 if (data < lastPktErr) {
4946 pktErr += 0xffff - lastPktErr;
4947 pktErr += data;
4948 } else {
4949 pktErr += (data - lastPktErr);
4950 }
4951 *packetErr = pktErr;
4952 lastPktErr = data;
4953
4954 return (DRX_STS_OK);
4955 rw_error:
4956 return (DRX_STS_ERROR);
4957 }
4958 #endif
4959
4960 /**
4961 * \fn DRXStatus_t ResetAccPktErr()
4962 * \brief Reset Accumulating packet error count.
4963 * \param demod Pointer to demod instance
4964 * \return DRXStatus_t.
4965 * \retval DRX_STS_OK.
4966 * \retval DRX_STS_ERROR Erroneous data.
4967 */
4968 static DRXStatus_t CtrlSetCfgResetPktErr(pDRXDemodInstance_t demod)
4969 {
4970 #ifdef DRXJ_SIGNAL_ACCUM_ERR
4971 pDRXJData_t extAttr = NULL;
4972 u16_t packetError = 0;
4973
4974 extAttr = (pDRXJData_t) demod->myExtAttr;
4975 extAttr->resetPktErrAcc = TRUE;
4976 /* call to reset counter */
4977 CHK_ERROR(GetAccPktErr(demod, &packetError));
4978
4979 return (DRX_STS_OK);
4980 rw_error:
4981 #endif
4982 return (DRX_STS_ERROR);
4983 }
4984
4985 /**
4986 * \fn static short GetSTRFreqOffset()
4987 * \brief Get symbol rate offset in QAM & 8VSB mode
4988 * \return Error code
4989 */
4990 static DRXStatus_t GetSTRFreqOffset(pDRXDemodInstance_t demod, s32_t * STRFreq)
4991 {
4992 u32_t symbolFrequencyRatio = 0;
4993 u32_t symbolNomFrequencyRatio = 0;
4994
4995 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
4996 pI2CDeviceAddr_t devAddr = NULL;
4997 pDRXJData_t extAttr = NULL;
4998
4999 devAddr = demod->myI2CDevAddr;
5000 extAttr = (pDRXJData_t) demod->myExtAttr;
5001 standard = extAttr->standard;
5002
5003 ARR32(devAddr, IQM_RC_RATE_LO__A, &symbolFrequencyRatio);
5004 symbolNomFrequencyRatio = extAttr->iqmRcRateOfs;
5005
5006 if (symbolFrequencyRatio > symbolNomFrequencyRatio)
5007 *STRFreq =
5008 -1 *
5009 FracTimes1e6((symbolFrequencyRatio -
5010 symbolNomFrequencyRatio),
5011 (symbolFrequencyRatio + (1 << 23)));
5012 else
5013 *STRFreq =
5014 FracTimes1e6((symbolNomFrequencyRatio -
5015 symbolFrequencyRatio),
5016 (symbolFrequencyRatio + (1 << 23)));
5017
5018 return (DRX_STS_OK);
5019 rw_error:
5020 return (DRX_STS_ERROR);
5021 }
5022
5023 /**
5024 * \fn static short GetCTLFreqOffset
5025 * \brief Get the value of CTLFreq in QAM & ATSC mode
5026 * \return Error code
5027 */
5028 static DRXStatus_t GetCTLFreqOffset(pDRXDemodInstance_t demod, s32_t * CTLFreq)
5029 {
5030 DRXFrequency_t samplingFrequency = 0;
5031 s32_t currentFrequency = 0;
5032 s32_t nominalFrequency = 0;
5033 s32_t carrierFrequencyShift = 0;
5034 s32_t sign = 1;
5035 u32_t data64Hi = 0;
5036 u32_t data64Lo = 0;
5037 pDRXJData_t extAttr = NULL;
5038 pDRXCommonAttr_t commonAttr = NULL;
5039 pI2CDeviceAddr_t devAddr = NULL;
5040
5041 devAddr = demod->myI2CDevAddr;
5042 extAttr = (pDRXJData_t) demod->myExtAttr;
5043 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
5044
5045 samplingFrequency = commonAttr->sysClockFreq / 3;
5046
5047 /* both registers are sign extended */
5048 nominalFrequency = extAttr->iqmFsRateOfs;
5049 ARR32(devAddr, IQM_FS_RATE_LO__A, (pu32_t) & currentFrequency);
5050
5051 if (extAttr->posImage == TRUE) {
5052 /* negative image */
5053 carrierFrequencyShift = nominalFrequency - currentFrequency;
5054 } else {
5055 /* positive image */
5056 carrierFrequencyShift = currentFrequency - nominalFrequency;
5057 }
5058
5059 /* carrier Frequency Shift In Hz */
5060 if (carrierFrequencyShift < 0) {
5061 sign = -1;
5062 carrierFrequencyShift *= sign;
5063 }
5064
5065 /* *CTLFreq = carrierFrequencyShift * 50.625e6 / (1 << 28); */
5066 Mult32(carrierFrequencyShift, samplingFrequency, &data64Hi, &data64Lo);
5067 *CTLFreq =
5068 (s32_t) ((((data64Lo >> 28) & 0xf) | (data64Hi << 4)) * sign);
5069
5070 return (DRX_STS_OK);
5071 rw_error:
5072 return (DRX_STS_ERROR);
5073 }
5074
5075 /*============================================================================*/
5076
5077 /**
5078 * \fn DRXStatus_t SetAgcRf ()
5079 * \brief Configure RF AGC
5080 * \param demod instance of demodulator.
5081 * \param agcSettings AGC configuration structure
5082 * \return DRXStatus_t.
5083 */
5084 static DRXStatus_t
5085 SetAgcRf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings, Bool_t atomic)
5086 {
5087 pI2CDeviceAddr_t devAddr = NULL;
5088 pDRXJData_t extAttr = NULL;
5089 pDRXJCfgAgc_t pAgcSettings = NULL;
5090 pDRXCommonAttr_t commonAttr = NULL;
5091 DRXWriteReg16Func_t ScuWr16 = NULL;
5092 DRXReadReg16Func_t ScuRr16 = NULL;
5093
5094 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
5095 devAddr = demod->myI2CDevAddr;
5096 extAttr = (pDRXJData_t) demod->myExtAttr;
5097
5098 if (atomic) {
5099 ScuRr16 = DRXJ_DAP_SCU_AtomicReadReg16;
5100 ScuWr16 = DRXJ_DAP_SCU_AtomicWriteReg16;
5101 } else {
5102 ScuRr16 = DRXJ_DAP.readReg16Func;
5103 ScuWr16 = DRXJ_DAP.writeReg16Func;
5104 }
5105
5106 /* Configure AGC only if standard is currently active */
5107 if ((extAttr->standard == agcSettings->standard) ||
5108 (DRXJ_ISQAMSTD(extAttr->standard) &&
5109 DRXJ_ISQAMSTD(agcSettings->standard)) ||
5110 (DRXJ_ISATVSTD(extAttr->standard) &&
5111 DRXJ_ISATVSTD(agcSettings->standard))) {
5112 u16_t data = 0;
5113
5114 switch (agcSettings->ctrlMode) {
5115 case DRX_AGC_CTRL_AUTO:
5116
5117 /* Enable RF AGC DAC */
5118 RR16(devAddr, IQM_AF_STDBY__A, &data);
5119 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5120 WR16(devAddr, IQM_AF_STDBY__A, data);
5121
5122 /* Enable SCU RF AGC loop */
5123 CHK_ERROR((*ScuRr16)
5124 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5125 data &= ~SCU_RAM_AGC_KI_RF__M;
5126 if (extAttr->standard == DRX_STANDARD_8VSB) {
5127 data |= (2 << SCU_RAM_AGC_KI_RF__B);
5128 } else if (DRXJ_ISQAMSTD(extAttr->standard)) {
5129 data |= (5 << SCU_RAM_AGC_KI_RF__B);
5130 } else {
5131 data |= (4 << SCU_RAM_AGC_KI_RF__B);
5132 }
5133
5134 if (commonAttr->tunerRfAgcPol) {
5135 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5136 } else {
5137 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5138 }
5139 CHK_ERROR((*ScuWr16)
5140 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5141
5142 /* Set speed ( using complementary reduction value ) */
5143 CHK_ERROR((*ScuRr16)
5144 (devAddr, SCU_RAM_AGC_KI_RED__A, &data, 0));
5145 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
5146 CHK_ERROR((*ScuWr16) (devAddr, SCU_RAM_AGC_KI_RED__A,
5147 (~
5148 (agcSettings->
5149 speed <<
5150 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
5151 & SCU_RAM_AGC_KI_RED_RAGC_RED__M)
5152 | data, 0));
5153
5154 if (agcSettings->standard == DRX_STANDARD_8VSB)
5155 pAgcSettings = &(extAttr->vsbIfAgcCfg);
5156 else if (DRXJ_ISQAMSTD(agcSettings->standard))
5157 pAgcSettings = &(extAttr->qamIfAgcCfg);
5158 else if (DRXJ_ISATVSTD(agcSettings->standard))
5159 pAgcSettings = &(extAttr->atvIfAgcCfg);
5160 else
5161 return (DRX_STS_INVALID_ARG);
5162
5163 /* Set TOP, only if IF-AGC is in AUTO mode */
5164 if (pAgcSettings->ctrlMode == DRX_AGC_CTRL_AUTO) {
5165 CHK_ERROR((*ScuWr16)
5166 (devAddr,
5167 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5168 agcSettings->top, 0));
5169 CHK_ERROR((*ScuWr16)
5170 (devAddr,
5171 SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
5172 agcSettings->top, 0));
5173 }
5174
5175 /* Cut-Off current */
5176 CHK_ERROR((*ScuWr16)
5177 (devAddr, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
5178 agcSettings->cutOffCurrent, 0));
5179 break;
5180 case DRX_AGC_CTRL_USER:
5181
5182 /* Enable RF AGC DAC */
5183 RR16(devAddr, IQM_AF_STDBY__A, &data);
5184 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5185 WR16(devAddr, IQM_AF_STDBY__A, data);
5186
5187 /* Disable SCU RF AGC loop */
5188 CHK_ERROR((*ScuRr16)
5189 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5190 data &= ~SCU_RAM_AGC_KI_RF__M;
5191 if (commonAttr->tunerRfAgcPol) {
5192 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5193 } else {
5194 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5195 }
5196 CHK_ERROR((*ScuWr16)
5197 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5198
5199 /* Write value to output pin */
5200 CHK_ERROR((*ScuWr16)
5201 (devAddr, SCU_RAM_AGC_RF_IACCU_HI__A,
5202 agcSettings->outputLevel, 0));
5203 break;
5204 case DRX_AGC_CTRL_OFF:
5205
5206 /* Disable RF AGC DAC */
5207 RR16(devAddr, IQM_AF_STDBY__A, &data);
5208 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5209 WR16(devAddr, IQM_AF_STDBY__A, data);
5210
5211 /* Disable SCU RF AGC loop */
5212 CHK_ERROR((*ScuRr16)
5213 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5214 data &= ~SCU_RAM_AGC_KI_RF__M;
5215 CHK_ERROR((*ScuWr16)
5216 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5217 break;
5218 default:
5219 return (DRX_STS_INVALID_ARG);
5220 } /* switch ( agcsettings->ctrlMode ) */
5221 }
5222
5223 /* Store rf agc settings */
5224 switch (agcSettings->standard) {
5225 case DRX_STANDARD_8VSB:
5226 extAttr->vsbRfAgcCfg = *agcSettings;
5227 break;
5228 #ifndef DRXJ_VSB_ONLY
5229 case DRX_STANDARD_ITU_A:
5230 case DRX_STANDARD_ITU_B:
5231 case DRX_STANDARD_ITU_C:
5232 extAttr->qamRfAgcCfg = *agcSettings;
5233 break;
5234 #endif
5235 #ifndef DRXJ_DIGITAL_ONLY
5236 case DRX_STANDARD_PAL_SECAM_BG:
5237 case DRX_STANDARD_PAL_SECAM_DK:
5238 case DRX_STANDARD_PAL_SECAM_I:
5239 case DRX_STANDARD_PAL_SECAM_L:
5240 case DRX_STANDARD_PAL_SECAM_LP:
5241 case DRX_STANDARD_NTSC:
5242 case DRX_STANDARD_FM:
5243 extAttr->atvRfAgcCfg = *agcSettings;
5244 break;
5245 #endif
5246 default:
5247 return (DRX_STS_ERROR);
5248 }
5249
5250 return (DRX_STS_OK);
5251 rw_error:
5252 return (DRX_STS_ERROR);
5253 }
5254
5255 /**
5256 * \fn DRXStatus_t GetAgcRf ()
5257 * \brief get configuration of RF AGC
5258 * \param demod instance of demodulator.
5259 * \param agcSettings AGC configuration structure
5260 * \return DRXStatus_t.
5261 */
5262 static DRXStatus_t
5263 GetAgcRf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
5264 {
5265 pI2CDeviceAddr_t devAddr = NULL;
5266 pDRXJData_t extAttr = NULL;
5267 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
5268
5269 devAddr = demod->myI2CDevAddr;
5270 extAttr = (pDRXJData_t) demod->myExtAttr;
5271
5272 /* Return stored AGC settings */
5273 standard = agcSettings->standard;
5274 switch (agcSettings->standard) {
5275 case DRX_STANDARD_8VSB:
5276 *agcSettings = extAttr->vsbRfAgcCfg;
5277 break;
5278 #ifndef DRXJ_VSB_ONLY
5279 case DRX_STANDARD_ITU_A:
5280 case DRX_STANDARD_ITU_B:
5281 case DRX_STANDARD_ITU_C:
5282 *agcSettings = extAttr->qamRfAgcCfg;
5283 break;
5284 #endif
5285 #ifndef DRXJ_DIGITAL_ONLY
5286 case DRX_STANDARD_PAL_SECAM_BG:
5287 case DRX_STANDARD_PAL_SECAM_DK:
5288 case DRX_STANDARD_PAL_SECAM_I:
5289 case DRX_STANDARD_PAL_SECAM_L:
5290 case DRX_STANDARD_PAL_SECAM_LP:
5291 case DRX_STANDARD_NTSC:
5292 case DRX_STANDARD_FM:
5293 *agcSettings = extAttr->atvRfAgcCfg;
5294 break;
5295 #endif
5296 default:
5297 return (DRX_STS_ERROR);
5298 }
5299 agcSettings->standard = standard;
5300
5301 /* Get AGC output only if standard is currently active. */
5302 if ((extAttr->standard == agcSettings->standard) ||
5303 (DRXJ_ISQAMSTD(extAttr->standard) &&
5304 DRXJ_ISQAMSTD(agcSettings->standard)) ||
5305 (DRXJ_ISATVSTD(extAttr->standard) &&
5306 DRXJ_ISATVSTD(agcSettings->standard))) {
5307 SARR16(devAddr, SCU_RAM_AGC_RF_IACCU_HI__A,
5308 &(agcSettings->outputLevel));
5309 }
5310
5311 return (DRX_STS_OK);
5312 rw_error:
5313 return (DRX_STS_ERROR);
5314 }
5315
5316 /**
5317 * \fn DRXStatus_t SetAgcIf ()
5318 * \brief Configure If AGC
5319 * \param demod instance of demodulator.
5320 * \param agcSettings AGC configuration structure
5321 * \return DRXStatus_t.
5322 */
5323 static DRXStatus_t
5324 SetAgcIf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings, Bool_t atomic)
5325 {
5326 pI2CDeviceAddr_t devAddr = NULL;
5327 pDRXJData_t extAttr = NULL;
5328 pDRXJCfgAgc_t pAgcSettings = NULL;
5329 pDRXCommonAttr_t commonAttr = NULL;
5330 DRXWriteReg16Func_t ScuWr16 = NULL;
5331 DRXReadReg16Func_t ScuRr16 = NULL;
5332
5333 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
5334 devAddr = demod->myI2CDevAddr;
5335 extAttr = (pDRXJData_t) demod->myExtAttr;
5336
5337 if (atomic) {
5338 ScuRr16 = DRXJ_DAP_SCU_AtomicReadReg16;
5339 ScuWr16 = DRXJ_DAP_SCU_AtomicWriteReg16;
5340 } else {
5341 ScuRr16 = DRXJ_DAP.readReg16Func;
5342 ScuWr16 = DRXJ_DAP.writeReg16Func;
5343 }
5344
5345 /* Configure AGC only if standard is currently active */
5346 if ((extAttr->standard == agcSettings->standard) ||
5347 (DRXJ_ISQAMSTD(extAttr->standard) &&
5348 DRXJ_ISQAMSTD(agcSettings->standard)) ||
5349 (DRXJ_ISATVSTD(extAttr->standard) &&
5350 DRXJ_ISATVSTD(agcSettings->standard))) {
5351 u16_t data = 0;
5352
5353 switch (agcSettings->ctrlMode) {
5354 case DRX_AGC_CTRL_AUTO:
5355 /* Enable IF AGC DAC */
5356 RR16(devAddr, IQM_AF_STDBY__A, &data);
5357 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5358 WR16(devAddr, IQM_AF_STDBY__A, data);
5359
5360 /* Enable SCU IF AGC loop */
5361 CHK_ERROR((*ScuRr16)
5362 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5363 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5364 data &= ~SCU_RAM_AGC_KI_IF__M;
5365 if (extAttr->standard == DRX_STANDARD_8VSB) {
5366 data |= (3 << SCU_RAM_AGC_KI_IF__B);
5367 } else if (DRXJ_ISQAMSTD(extAttr->standard)) {
5368 data |= (6 << SCU_RAM_AGC_KI_IF__B);
5369 } else {
5370 data |= (5 << SCU_RAM_AGC_KI_IF__B);
5371 }
5372
5373 if (commonAttr->tunerIfAgcPol) {
5374 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5375 } else {
5376 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5377 }
5378 CHK_ERROR((*ScuWr16)
5379 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5380
5381 /* Set speed (using complementary reduction value) */
5382 CHK_ERROR((*ScuRr16)
5383 (devAddr, SCU_RAM_AGC_KI_RED__A, &data, 0));
5384 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
5385 CHK_ERROR((*ScuWr16) (devAddr, SCU_RAM_AGC_KI_RED__A,
5386 (~
5387 (agcSettings->
5388 speed <<
5389 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
5390 & SCU_RAM_AGC_KI_RED_IAGC_RED__M)
5391 | data, 0));
5392
5393 if (agcSettings->standard == DRX_STANDARD_8VSB)
5394 pAgcSettings = &(extAttr->vsbRfAgcCfg);
5395 else if (DRXJ_ISQAMSTD(agcSettings->standard))
5396 pAgcSettings = &(extAttr->qamRfAgcCfg);
5397 else if (DRXJ_ISATVSTD(agcSettings->standard))
5398 pAgcSettings = &(extAttr->atvRfAgcCfg);
5399 else
5400 return (DRX_STS_INVALID_ARG);
5401
5402 /* Restore TOP */
5403 if (pAgcSettings->ctrlMode == DRX_AGC_CTRL_AUTO) {
5404 CHK_ERROR((*ScuWr16)
5405 (devAddr,
5406 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5407 pAgcSettings->top, 0));
5408 CHK_ERROR((*ScuWr16)
5409 (devAddr,
5410 SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
5411 pAgcSettings->top, 0));
5412 } else {
5413 CHK_ERROR((*ScuWr16)
5414 (devAddr,
5415 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5416 0, 0));
5417 CHK_ERROR((*ScuWr16)
5418 (devAddr,
5419 SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0,
5420 0));
5421 }
5422 break;
5423
5424 case DRX_AGC_CTRL_USER:
5425
5426 /* Enable IF AGC DAC */
5427 RR16(devAddr, IQM_AF_STDBY__A, &data);
5428 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5429 WR16(devAddr, IQM_AF_STDBY__A, data);
5430
5431 /* Disable SCU IF AGC loop */
5432 CHK_ERROR((*ScuRr16)
5433 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5434 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5435 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5436 if (commonAttr->tunerIfAgcPol) {
5437 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5438 } else {
5439 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5440 }
5441 CHK_ERROR((*ScuWr16)
5442 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5443
5444 /* Write value to output pin */
5445 CHK_ERROR((*ScuWr16)
5446 (devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5447 agcSettings->outputLevel, 0));
5448 break;
5449
5450 case DRX_AGC_CTRL_OFF:
5451
5452 /* Disable If AGC DAC */
5453 RR16(devAddr, IQM_AF_STDBY__A, &data);
5454 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
5455 WR16(devAddr, IQM_AF_STDBY__A, data);
5456
5457 /* Disable SCU IF AGC loop */
5458 CHK_ERROR((*ScuRr16)
5459 (devAddr, SCU_RAM_AGC_KI__A, &data, 0));
5460 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5461 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5462 CHK_ERROR((*ScuWr16)
5463 (devAddr, SCU_RAM_AGC_KI__A, data, 0));
5464 break;
5465 default:
5466 return (DRX_STS_INVALID_ARG);
5467 } /* switch ( agcsettings->ctrlMode ) */
5468
5469 /* always set the top to support configurations without if-loop */
5470 CHK_ERROR((*ScuWr16) (devAddr,
5471 SCU_RAM_AGC_INGAIN_TGT_MIN__A,
5472 agcSettings->top, 0));
5473 }
5474
5475 /* Store if agc settings */
5476 switch (agcSettings->standard) {
5477 case DRX_STANDARD_8VSB:
5478 extAttr->vsbIfAgcCfg = *agcSettings;
5479 break;
5480 #ifndef DRXJ_VSB_ONLY
5481 case DRX_STANDARD_ITU_A:
5482 case DRX_STANDARD_ITU_B:
5483 case DRX_STANDARD_ITU_C:
5484 extAttr->qamIfAgcCfg = *agcSettings;
5485 break;
5486 #endif
5487 #ifndef DRXJ_DIGITAL_ONLY
5488 case DRX_STANDARD_PAL_SECAM_BG:
5489 case DRX_STANDARD_PAL_SECAM_DK:
5490 case DRX_STANDARD_PAL_SECAM_I:
5491 case DRX_STANDARD_PAL_SECAM_L:
5492 case DRX_STANDARD_PAL_SECAM_LP:
5493 case DRX_STANDARD_NTSC:
5494 case DRX_STANDARD_FM:
5495 extAttr->atvIfAgcCfg = *agcSettings;
5496 break;
5497 #endif
5498 default:
5499 return (DRX_STS_ERROR);
5500 }
5501
5502 return (DRX_STS_OK);
5503 rw_error:
5504 return (DRX_STS_ERROR);
5505 }
5506
5507 /**
5508 * \fn DRXStatus_t GetAgcIf ()
5509 * \brief get configuration of If AGC
5510 * \param demod instance of demodulator.
5511 * \param agcSettings AGC configuration structure
5512 * \return DRXStatus_t.
5513 */
5514 static DRXStatus_t
5515 GetAgcIf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
5516 {
5517 pI2CDeviceAddr_t devAddr = NULL;
5518 pDRXJData_t extAttr = NULL;
5519 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
5520
5521 devAddr = demod->myI2CDevAddr;
5522 extAttr = (pDRXJData_t) demod->myExtAttr;
5523
5524 /* Return stored ATV AGC settings */
5525 standard = agcSettings->standard;
5526 switch (agcSettings->standard) {
5527 case DRX_STANDARD_8VSB:
5528 *agcSettings = extAttr->vsbIfAgcCfg;
5529 break;
5530 #ifndef DRXJ_VSB_ONLY
5531 case DRX_STANDARD_ITU_A:
5532 case DRX_STANDARD_ITU_B:
5533 case DRX_STANDARD_ITU_C:
5534 *agcSettings = extAttr->qamIfAgcCfg;
5535 break;
5536 #endif
5537 #ifndef DRXJ_DIGITAL_ONLY
5538 case DRX_STANDARD_PAL_SECAM_BG:
5539 case DRX_STANDARD_PAL_SECAM_DK:
5540 case DRX_STANDARD_PAL_SECAM_I:
5541 case DRX_STANDARD_PAL_SECAM_L:
5542 case DRX_STANDARD_PAL_SECAM_LP:
5543 case DRX_STANDARD_NTSC:
5544 case DRX_STANDARD_FM:
5545 *agcSettings = extAttr->atvIfAgcCfg;
5546 break;
5547 #endif
5548 default:
5549 return (DRX_STS_ERROR);
5550 }
5551 agcSettings->standard = standard;
5552
5553 /* Get AGC output only if standard is currently active */
5554 if ((extAttr->standard == agcSettings->standard) ||
5555 (DRXJ_ISQAMSTD(extAttr->standard) &&
5556 DRXJ_ISQAMSTD(agcSettings->standard)) ||
5557 (DRXJ_ISATVSTD(extAttr->standard) &&
5558 DRXJ_ISATVSTD(agcSettings->standard))) {
5559 /* read output level */
5560 SARR16(devAddr, SCU_RAM_AGC_IF_IACCU_HI__A,
5561 &(agcSettings->outputLevel));
5562 }
5563
5564 return (DRX_STS_OK);
5565 rw_error:
5566 return (DRX_STS_ERROR);
5567 }
5568
5569 /**
5570 * \fn DRXStatus_t SetIqmAf ()
5571 * \brief Configure IQM AF registers
5572 * \param demod instance of demodulator.
5573 * \param active
5574 * \return DRXStatus_t.
5575 */
5576 static DRXStatus_t SetIqmAf(pDRXDemodInstance_t demod, Bool_t active)
5577 {
5578 u16_t data = 0;
5579 pI2CDeviceAddr_t devAddr = NULL;
5580
5581 devAddr = demod->myI2CDevAddr;
5582
5583 /* Configure IQM */
5584 RR16(devAddr, IQM_AF_STDBY__A, &data);
5585 if (!active) {
5586 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
5587 & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
5588 & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
5589 & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
5590 & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
5591 );
5592 } else { /* active */
5593
5594 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
5595 | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
5596 | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
5597 | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
5598 | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5599 }
5600 WR16(devAddr, IQM_AF_STDBY__A, data);
5601
5602 return (DRX_STS_OK);
5603 rw_error:
5604 return (DRX_STS_ERROR);
5605 }
5606
5607 /*============================================================================*/
5608 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5609 /*============================================================================*/
5610
5611 /*============================================================================*/
5612 /*============================================================================*/
5613 /*== 8VSB DATAPATH FUNCTIONS ==*/
5614 /*============================================================================*/
5615 /*============================================================================*/
5616
5617 /**
5618 * \fn DRXStatus_t PowerDownVSB ()
5619 * \brief Powr down QAM related blocks.
5620 * \param demod instance of demodulator.
5621 * \param channel pointer to channel data.
5622 * \return DRXStatus_t.
5623 */
5624 static DRXStatus_t PowerDownVSB(pDRXDemodInstance_t demod, Bool_t primary)
5625 {
5626 pI2CDeviceAddr_t devAddr = NULL;
5627 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
5628 /* parameterLen */ 0,
5629 /* resultLen */ 0,
5630 /* *parameter */ NULL,
5631 /* *result */ NULL
5632 };
5633 u16_t cmdResult = 0;
5634 pDRXJData_t extAttr = NULL;
5635 DRXCfgMPEGOutput_t cfgMPEGOutput;
5636
5637 devAddr = demod->myI2CDevAddr;
5638 extAttr = (pDRXJData_t) demod->myExtAttr;
5639 /*
5640 STOP demodulator
5641 reset of FEC and VSB HW
5642 */
5643 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB |
5644 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
5645 cmdSCU.parameterLen = 0;
5646 cmdSCU.resultLen = 1;
5647 cmdSCU.parameter = NULL;
5648 cmdSCU.result = &cmdResult;
5649 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
5650
5651 /* stop all comm_exec */
5652 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5653 WR16(devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP);
5654 if (primary == TRUE) {
5655 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
5656 CHK_ERROR(SetIqmAf(demod, FALSE));
5657 } else {
5658 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
5659 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
5660 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
5661 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
5662 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
5663 }
5664
5665 cfgMPEGOutput.enableMPEGOutput = FALSE;
5666 CHK_ERROR(CtrlSetCfgMPEGOutput(demod, &cfgMPEGOutput));
5667
5668 return (DRX_STS_OK);
5669 rw_error:
5670 return (DRX_STS_ERROR);
5671 }
5672
5673 /**
5674 * \fn DRXStatus_t SetVSBLeakNGain ()
5675 * \brief Set ATSC demod.
5676 * \param demod instance of demodulator.
5677 * \return DRXStatus_t.
5678 */
5679 static DRXStatus_t SetVSBLeakNGain(pDRXDemodInstance_t demod)
5680 {
5681 pI2CDeviceAddr_t devAddr = NULL;
5682
5683 const u8_t vsb_ffe_leak_gain_ram0[] = {
5684 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5685 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5686 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5687 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5688 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5689 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5690 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5691 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5692 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5693 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5694 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5695 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5696 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5697 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5698 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5699 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5700 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5701 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5702 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5703 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5704 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5705 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5706 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5707 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5708 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5709 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5710 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5711 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5712 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5713 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5714 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5715 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5716 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5717 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5718 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5719 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5720 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5721 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5722 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5723 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5724 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5725 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5726 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5727 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5728 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5729 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5730 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5731 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5732 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5733 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5734 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5735 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5736 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5737 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5738 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5739 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5740 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5741 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5742 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5743 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5744 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5745 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5746 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5747 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5748 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5749 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5750 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5751 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5752 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5753 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5754 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5755 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5756 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5757 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5758 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5759 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5760 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5761 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5762 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5763 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5764 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5765 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5766 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5767 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5768 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5769 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5770 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5771 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5772 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5773 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5774 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5775 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5776 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5777 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5778 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5779 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5780 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5781 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5782 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5783 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5784 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5785 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5786 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5787 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5788 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5789 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5790 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5791 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5792 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5793 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5794 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5795 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5796 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5797 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5798 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5799 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5800 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5801 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5802 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5803 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5804 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5805 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5806 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5807 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5808 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5809 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5810 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5811 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5812 };
5813
5814 const u8_t vsb_ffe_leak_gain_ram1[] = {
5815 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5816 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5817 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5818 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5819 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5820 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5821 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5822 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5823 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5824 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5825 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5826 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5827 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5828 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5829 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5830 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5831 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5832 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5833 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5834 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5835 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5836 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5837 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5838 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5839 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5840 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5841 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5842 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5843 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5844 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5845 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5846 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5847 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5848 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5849 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5850 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5851 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5852 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5853 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5854 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5855 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5856 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5857 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5858 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5859 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5860 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5861 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5862 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5863 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5864 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5865 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5866 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5867 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5868 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5869 };
5870
5871 devAddr = demod->myI2CDevAddr;
5872 WRB(devAddr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A,
5873 sizeof(vsb_ffe_leak_gain_ram0), ((pu8_t) vsb_ffe_leak_gain_ram0));
5874 WRB(devAddr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A,
5875 sizeof(vsb_ffe_leak_gain_ram1), ((pu8_t) vsb_ffe_leak_gain_ram1));
5876
5877 return (DRX_STS_OK);
5878 rw_error:
5879 return (DRX_STS_ERROR);
5880 }
5881
5882 /**
5883 * \fn DRXStatus_t SetVSB()
5884 * \brief Set 8VSB demod.
5885 * \param demod instance of demodulator.
5886 * \return DRXStatus_t.
5887 *
5888 */
5889 static DRXStatus_t SetVSB(pDRXDemodInstance_t demod)
5890 {
5891 pI2CDeviceAddr_t devAddr = NULL;
5892 u16_t cmdResult = 0;
5893 u16_t cmdParam = 0;
5894 pDRXCommonAttr_t commonAttr = NULL;
5895 DRXJSCUCmd_t cmdSCU;
5896 pDRXJData_t extAttr = NULL;
5897 const u8_t vsb_taps_re[] = {
5898 DRXJ_16TO8(-2), /* re0 */
5899 DRXJ_16TO8(4), /* re1 */
5900 DRXJ_16TO8(1), /* re2 */
5901 DRXJ_16TO8(-4), /* re3 */
5902 DRXJ_16TO8(1), /* re4 */
5903 DRXJ_16TO8(4), /* re5 */
5904 DRXJ_16TO8(-3), /* re6 */
5905 DRXJ_16TO8(-3), /* re7 */
5906 DRXJ_16TO8(6), /* re8 */
5907 DRXJ_16TO8(1), /* re9 */
5908 DRXJ_16TO8(-9), /* re10 */
5909 DRXJ_16TO8(3), /* re11 */
5910 DRXJ_16TO8(12), /* re12 */
5911 DRXJ_16TO8(-9), /* re13 */
5912 DRXJ_16TO8(-15), /* re14 */
5913 DRXJ_16TO8(17), /* re15 */
5914 DRXJ_16TO8(19), /* re16 */
5915 DRXJ_16TO8(-29), /* re17 */
5916 DRXJ_16TO8(-22), /* re18 */
5917 DRXJ_16TO8(45), /* re19 */
5918 DRXJ_16TO8(25), /* re20 */
5919 DRXJ_16TO8(-70), /* re21 */
5920 DRXJ_16TO8(-28), /* re22 */
5921 DRXJ_16TO8(111), /* re23 */
5922 DRXJ_16TO8(30), /* re24 */
5923 DRXJ_16TO8(-201), /* re25 */
5924 DRXJ_16TO8(-31), /* re26 */
5925 DRXJ_16TO8(629) /* re27 */
5926 };
5927
5928 devAddr = demod->myI2CDevAddr;
5929 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
5930 extAttr = (pDRXJData_t) demod->myExtAttr;
5931
5932 /* stop all comm_exec */
5933 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5934 WR16(devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP);
5935 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
5936 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
5937 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
5938 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
5939 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
5940
5941 /* reset demodulator */
5942 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
5943 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
5944 cmdSCU.parameterLen = 0;
5945 cmdSCU.resultLen = 1;
5946 cmdSCU.parameter = NULL;
5947 cmdSCU.result = &cmdResult;
5948 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
5949
5950 WR16(devAddr, IQM_AF_DCF_BYPASS__A, 1);
5951 WR16(devAddr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB);
5952 WR16(devAddr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB);
5953 extAttr->iqmRcRateOfs = 0x00AD0D79;
5954 WR32(devAddr, IQM_RC_RATE_OFS_LO__A, extAttr->iqmRcRateOfs);
5955 WR16(devAddr, VSB_TOP_CFAGC_GAINSHIFT__A, 4);
5956 WR16(devAddr, VSB_TOP_CYGN1TRK__A, 1);
5957
5958 WR16(devAddr, IQM_RC_CROUT_ENA__A, 1);
5959 WR16(devAddr, IQM_RC_STRETCH__A, 28);
5960 WR16(devAddr, IQM_RT_ACTIVE__A, 0);
5961 WR16(devAddr, IQM_CF_SYMMETRIC__A, 0);
5962 WR16(devAddr, IQM_CF_MIDTAP__A, 3);
5963 WR16(devAddr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M);
5964 WR16(devAddr, IQM_CF_SCALE__A, 1393);
5965 WR16(devAddr, IQM_CF_SCALE_SH__A, 0);
5966 WR16(devAddr, IQM_CF_POW_MEAS_LEN__A, 1);
5967
5968 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re),
5969 ((pu8_t) vsb_taps_re));
5970 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re),
5971 ((pu8_t) vsb_taps_re));
5972
5973 WR16(devAddr, VSB_TOP_BNTHRESH__A, 330); /* set higher threshold */
5974 WR16(devAddr, VSB_TOP_CLPLASTNUM__A, 90); /* burst detection on */
5975 WR16(devAddr, VSB_TOP_SNRTH_RCA1__A, 0x0042); /* drop thresholds by 1 dB */
5976 WR16(devAddr, VSB_TOP_SNRTH_RCA2__A, 0x0053); /* drop thresholds by 2 dB */
5977 WR16(devAddr, VSB_TOP_EQCTRL__A, 0x1); /* cma on */
5978 WR16(devAddr, SCU_RAM_GPIO__A, 0); /* GPIO */
5979
5980 /* Initialize the FEC Subsystem */
5981 WR16(devAddr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D);
5982 {
5983 u16_t fecOcSncMode = 0;
5984 RR16(devAddr, FEC_OC_SNC_MODE__A, &fecOcSncMode);
5985 /* output data even when not locked */
5986 WR16(devAddr, FEC_OC_SNC_MODE__A,
5987 fecOcSncMode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M);
5988 }
5989
5990 /* set clip */
5991 WR16(devAddr, IQM_AF_CLP_LEN__A, 0);
5992 WR16(devAddr, IQM_AF_CLP_TH__A, 470);
5993 WR16(devAddr, IQM_AF_SNS_LEN__A, 0);
5994 WR16(devAddr, VSB_TOP_SNRTH_PT__A, 0xD4);
5995 /* no transparent, no A&C framing; parity is set in mpegoutput */
5996 {
5997 u16_t fecOcRegMode = 0;
5998 RR16(devAddr, FEC_OC_MODE__A, &fecOcRegMode);
5999 WR16(devAddr, FEC_OC_MODE__A, fecOcRegMode &
6000 (~(FEC_OC_MODE_TRANSPARENT__M
6001 | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)
6002 ));
6003 }
6004
6005 WR16(devAddr, FEC_DI_TIMEOUT_LO__A, 0); /* timeout counter for restarting */
6006 WR16(devAddr, FEC_DI_TIMEOUT_HI__A, 3);
6007 WR16(devAddr, FEC_RS_MODE__A, 0); /* bypass disabled */
6008 /* initialize RS packet error measurement parameters */
6009 WR16(devAddr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD);
6010 WR16(devAddr, FEC_RS_MEASUREMENT_PRESCALE__A,
6011 FEC_RS_MEASUREMENT_PRESCALE);
6012
6013 /* init measurement period of MER/SER */
6014 WR16(devAddr, VSB_TOP_MEASUREMENT_PERIOD__A,
6015 VSB_TOP_MEASUREMENT_PERIOD);
6016 WR32(devAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0);
6017 WR16(devAddr, SCU_RAM_FEC_MEAS_COUNT__A, 0);
6018 WR16(devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6019
6020 WR16(devAddr, VSB_TOP_CKGN1TRK__A, 128);
6021 /* B-Input to ADC, PGA+filter in standby */
6022 if (extAttr->hasLNA == FALSE) {
6023 WR16(devAddr, IQM_AF_AMUX__A, 0x02);
6024 };
6025
6026 /* turn on IQMAF. It has to be in front of setAgc**() */
6027 CHK_ERROR(SetIqmAf(demod, TRUE));
6028 CHK_ERROR(ADCSynchronization(demod));
6029
6030 CHK_ERROR(InitAGC(demod));
6031 CHK_ERROR(SetAgcIf(demod, &(extAttr->vsbIfAgcCfg), FALSE));
6032 CHK_ERROR(SetAgcRf(demod, &(extAttr->vsbRfAgcCfg), FALSE));
6033 {
6034 /* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
6035 of only the gain */
6036 DRXJCfgAfeGain_t vsbPgaCfg = { DRX_STANDARD_8VSB, 0 };
6037
6038 vsbPgaCfg.gain = extAttr->vsbPgaCfg;
6039 CHK_ERROR(CtrlSetCfgAfeGain(demod, &vsbPgaCfg));
6040 }
6041 CHK_ERROR(CtrlSetCfgPreSaw(demod, &(extAttr->vsbPreSawCfg)));
6042
6043 /* Mpeg output has to be in front of FEC active */
6044 CHK_ERROR(SetMPEGTEIHandling(demod));
6045 CHK_ERROR(BitReverseMPEGOutput(demod));
6046 CHK_ERROR(SetMPEGStartWidth(demod));
6047 {
6048 /* TODO: move to setStandard after hardware reset value problem is solved */
6049 /* Configure initial MPEG output */
6050 DRXCfgMPEGOutput_t cfgMPEGOutput;
6051 cfgMPEGOutput.enableMPEGOutput = TRUE;
6052 cfgMPEGOutput.insertRSByte = commonAttr->mpegCfg.insertRSByte;
6053 cfgMPEGOutput.enableParallel =
6054 commonAttr->mpegCfg.enableParallel;
6055 cfgMPEGOutput.invertDATA = commonAttr->mpegCfg.invertDATA;
6056 cfgMPEGOutput.invertERR = commonAttr->mpegCfg.invertERR;
6057 cfgMPEGOutput.invertSTR = commonAttr->mpegCfg.invertSTR;
6058 cfgMPEGOutput.invertVAL = commonAttr->mpegCfg.invertVAL;
6059 cfgMPEGOutput.invertCLK = commonAttr->mpegCfg.invertCLK;
6060 cfgMPEGOutput.staticCLK = commonAttr->mpegCfg.staticCLK;
6061 cfgMPEGOutput.bitrate = commonAttr->mpegCfg.bitrate;
6062 CHK_ERROR(CtrlSetCfgMPEGOutput(demod, &cfgMPEGOutput));
6063 }
6064
6065 /* TBD: what parameters should be set */
6066 cmdParam = 0x00; /* Default mode AGC on, etc */
6067 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
6068 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
6069 cmdSCU.parameterLen = 1;
6070 cmdSCU.resultLen = 1;
6071 cmdSCU.parameter = &cmdParam;
6072 cmdSCU.result = &cmdResult;
6073 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
6074
6075 WR16(devAddr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004);
6076 WR16(devAddr, VSB_TOP_SNRTH_PT__A, 0x00D2);
6077 WR16(devAddr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE
6078 | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M);
6079 WR16(devAddr, VSB_TOP_BEDETCTRL__A, 0x142);
6080 WR16(devAddr, VSB_TOP_LBAGCREFLVL__A, 640);
6081 WR16(devAddr, VSB_TOP_CYGN1ACQ__A, 4);
6082 WR16(devAddr, VSB_TOP_CYGN1TRK__A, 2);
6083 WR16(devAddr, VSB_TOP_CYGN2TRK__A, 3);
6084
6085 /* start demodulator */
6086 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
6087 | SCU_RAM_COMMAND_CMD_DEMOD_START;
6088 cmdSCU.parameterLen = 0;
6089 cmdSCU.resultLen = 1;
6090 cmdSCU.parameter = NULL;
6091 cmdSCU.result = &cmdResult;
6092 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
6093
6094 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
6095 WR16(devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE);
6096 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
6097
6098 return (DRX_STS_OK);
6099 rw_error:
6100 return (DRX_STS_ERROR);
6101 }
6102
6103 /**
6104 * \fn static short GetVSBPostRSPckErr(pI2CDeviceAddr_t devAddr, pu16_t PckErrs)
6105 * \brief Get the values of packet error in 8VSB mode
6106 * \return Error code
6107 */
6108 static DRXStatus_t GetVSBPostRSPckErr(pI2CDeviceAddr_t devAddr, pu16_t pckErrs)
6109 {
6110 u16_t data = 0;
6111 u16_t period = 0;
6112 u16_t prescale = 0;
6113 u16_t packetErrorsMant = 0;
6114 u16_t packetErrorsExp = 0;
6115
6116 RR16(devAddr, FEC_RS_NR_FAILURES__A, &data);
6117 packetErrorsMant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6118 packetErrorsExp = (data & FEC_RS_NR_FAILURES_EXP__M)
6119 >> FEC_RS_NR_FAILURES_EXP__B;
6120 period = FEC_RS_MEASUREMENT_PERIOD;
6121 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6122 /* packet error rate = (error packet number) per second */
6123 /* 77.3 us is time for per packet */
6124 CHK_ZERO(period * prescale);
6125 *pckErrs =
6126 (u16_t) FracTimes1e6(packetErrorsMant * (1 << packetErrorsExp),
6127 (period * prescale * 77));
6128
6129 return (DRX_STS_OK);
6130 rw_error:
6131 return (DRX_STS_ERROR);
6132 }
6133
6134 /**
6135 * \fn static short GetVSBBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
6136 * \brief Get the values of ber in VSB mode
6137 * \return Error code
6138 */
6139 static DRXStatus_t GetVSBpostViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
6140 {
6141 u16_t data = 0;
6142 u16_t period = 0;
6143 u16_t prescale = 0;
6144 u16_t bitErrorsMant = 0;
6145 u16_t bitErrorsExp = 0;
6146
6147 RR16(devAddr, FEC_RS_NR_BIT_ERRORS__A, &data);
6148 period = FEC_RS_MEASUREMENT_PERIOD;
6149 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6150
6151 bitErrorsMant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6152 bitErrorsExp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6153 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6154
6155 if (((bitErrorsMant << bitErrorsExp) >> 3) > 68700)
6156 *ber = 26570;
6157 else {
6158 CHK_ZERO(period * prescale);
6159 *ber =
6160 FracTimes1e6(bitErrorsMant <<
6161 ((bitErrorsExp >
6162 2) ? (bitErrorsExp - 3) : bitErrorsExp),
6163 period * prescale * 207 *
6164 ((bitErrorsExp > 2) ? 1 : 8));
6165 }
6166
6167 return (DRX_STS_OK);
6168 rw_error:
6169 return (DRX_STS_ERROR);
6170 }
6171
6172 /**
6173 * \fn static short GetVSBpreViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
6174 * \brief Get the values of ber in VSB mode
6175 * \return Error code
6176 */
6177 static DRXStatus_t GetVSBpreViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
6178 {
6179 u16_t data = 0;
6180
6181 RR16(devAddr, VSB_TOP_NR_SYM_ERRS__A, &data);
6182 *ber =
6183 FracTimes1e6(data,
6184 VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
6185
6186 return (DRX_STS_OK);
6187 rw_error:
6188 return (DRX_STS_ERROR);
6189 }
6190
6191 /**
6192 * \fn static short GetVSBSymbErr(pI2CDeviceAddr_t devAddr, pu32_t ber)
6193 * \brief Get the values of ber in VSB mode
6194 * \return Error code
6195 */
6196 static DRXStatus_t GetVSBSymbErr(pI2CDeviceAddr_t devAddr, pu32_t ser)
6197 {
6198 u16_t data = 0;
6199 u16_t period = 0;
6200 u16_t prescale = 0;
6201 u16_t symbErrorsMant = 0;
6202 u16_t symbErrorsExp = 0;
6203
6204 RR16(devAddr, FEC_RS_NR_SYMBOL_ERRORS__A, &data);
6205 period = FEC_RS_MEASUREMENT_PERIOD;
6206 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6207
6208 symbErrorsMant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
6209 symbErrorsExp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
6210 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
6211
6212 CHK_ZERO(period * prescale);
6213 *ser = (u32_t) FracTimes1e6((symbErrorsMant << symbErrorsExp) * 1000,
6214 (period * prescale * 77318));
6215
6216 return (DRX_STS_OK);
6217 rw_error:
6218 return (DRX_STS_ERROR);
6219 }
6220
6221 /**
6222 * \fn static DRXStatus_t GetVSBMER(pI2CDeviceAddr_t devAddr, pu16_t mer)
6223 * \brief Get the values of MER
6224 * \return Error code
6225 */
6226 static DRXStatus_t GetVSBMER(pI2CDeviceAddr_t devAddr, pu16_t mer)
6227 {
6228 u16_t dataHi = 0;
6229
6230 RR16(devAddr, VSB_TOP_ERR_ENERGY_H__A, &dataHi);
6231 *mer =
6232 (u16_t) (Log10Times100(21504) - Log10Times100((dataHi << 6) / 52));
6233
6234 return (DRX_STS_OK);
6235 rw_error:
6236 return (DRX_STS_ERROR);
6237 }
6238
6239 /*============================================================================*/
6240 /**
6241 * \fn DRXStatus_t CtrlGetVSBConstel()
6242 * \brief Retreive a VSB constellation point via I2C.
6243 * \param demod Pointer to demodulator instance.
6244 * \param complexNr Pointer to the structure in which to store the
6245 constellation point.
6246 * \return DRXStatus_t.
6247 */
6248 static DRXStatus_t
6249 CtrlGetVSBConstel(pDRXDemodInstance_t demod, pDRXComplex_t complexNr)
6250 {
6251 pI2CDeviceAddr_t devAddr = NULL;
6252 /**< device address */
6253 u16_t vsbTopCommMb = 0; /**< VSB SL MB configuration */
6254 u16_t vsbTopCommMbInit = 0; /**< VSB SL MB intial configuration */
6255 u16_t re = 0; /**< constellation Re part */
6256 u32_t data = 0;
6257
6258 /* read device info */
6259 devAddr = demod->myI2CDevAddr;
6260
6261 /* TODO: */
6262 /* Monitor bus grabbing is an open external interface issue */
6263 /* Needs to be checked when external interface PG is updated */
6264
6265 /* Configure MB (Monitor bus) */
6266 RR16(devAddr, VSB_TOP_COMM_MB__A, &vsbTopCommMbInit);
6267 /* set observe flag & MB mux */
6268 vsbTopCommMb = (vsbTopCommMbInit |
6269 VSB_TOP_COMM_MB_OBS_OBS_ON |
6270 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
6271 WR16(devAddr, VSB_TOP_COMM_MB__A, vsbTopCommMb);
6272
6273 /* Enable MB grabber in the FEC OC */
6274 WR16(devAddr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M);
6275
6276 /* Disable MB grabber in the FEC OC */
6277 WR16(devAddr, FEC_OC_OCR_MODE__A, 0x0);
6278
6279 /* read data */
6280 RR32(devAddr, FEC_OC_OCR_GRAB_RD1__A, &data);
6281 re = (u16_t) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
6282 if (re & 0x0200) {
6283 re |= 0xfc00;
6284 }
6285 complexNr->re = re;
6286 complexNr->im = 0;
6287
6288 /* Restore MB (Monitor bus) */
6289 WR16(devAddr, VSB_TOP_COMM_MB__A, vsbTopCommMbInit);
6290
6291 return (DRX_STS_OK);
6292 rw_error:
6293 return (DRX_STS_ERROR);
6294 }
6295
6296 /*============================================================================*/
6297 /*== END 8VSB DATAPATH FUNCTIONS ==*/
6298 /*============================================================================*/
6299
6300 /*============================================================================*/
6301 /*============================================================================*/
6302 /*== QAM DATAPATH FUNCTIONS ==*/
6303 /*============================================================================*/
6304 /*============================================================================*/
6305
6306 /**
6307 * \fn DRXStatus_t PowerDownQAM ()
6308 * \brief Powr down QAM related blocks.
6309 * \param demod instance of demodulator.
6310 * \param channel pointer to channel data.
6311 * \return DRXStatus_t.
6312 */
6313 static DRXStatus_t PowerDownQAM(pDRXDemodInstance_t demod, Bool_t primary)
6314 {
6315 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
6316 /* parameterLen */ 0,
6317 /* resultLen */ 0,
6318 /* *parameter */ NULL,
6319 /* *result */ NULL
6320 };
6321 u16_t cmdResult = 0;
6322 pI2CDeviceAddr_t devAddr = NULL;
6323 pDRXJData_t extAttr = NULL;
6324 DRXCfgMPEGOutput_t cfgMPEGOutput;
6325
6326 devAddr = demod->myI2CDevAddr;
6327 extAttr = (pDRXJData_t) demod->myExtAttr;
6328
6329 /*
6330 STOP demodulator
6331 resets IQM, QAM and FEC HW blocks
6332 */
6333 /* stop all comm_exec */
6334 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6335 WR16(devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
6336
6337 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
6338 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6339 cmdSCU.parameterLen = 0;
6340 cmdSCU.resultLen = 1;
6341 cmdSCU.parameter = NULL;
6342 cmdSCU.result = &cmdResult;
6343 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
6344
6345 if (primary == TRUE) {
6346 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
6347 CHK_ERROR(SetIqmAf(demod, FALSE));
6348 } else {
6349 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
6350 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
6351 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
6352 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
6353 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
6354 }
6355
6356 cfgMPEGOutput.enableMPEGOutput = FALSE;
6357 CHK_ERROR(CtrlSetCfgMPEGOutput(demod, &cfgMPEGOutput));
6358
6359 return (DRX_STS_OK);
6360 rw_error:
6361 return (DRX_STS_ERROR);
6362 }
6363
6364 /*============================================================================*/
6365
6366 /**
6367 * \fn DRXStatus_t SetQAMMeasurement ()
6368 * \brief Setup of the QAM Measuremnt intervals for signal quality
6369 * \param demod instance of demod.
6370 * \param constellation current constellation.
6371 * \return DRXStatus_t.
6372 *
6373 * NOTE:
6374 * Take into account that for certain settings the errorcounters can overflow.
6375 * The implementation does not check this.
6376 *
6377 * TODO: overriding the extAttr->fecBitsDesired by constellation dependent
6378 * constants to get a measurement period of approx. 1 sec. Remove fecBitsDesired
6379 * field ?
6380 *
6381 */
6382 #ifndef DRXJ_VSB_ONLY
6383 static DRXStatus_t
6384 SetQAMMeasurement(pDRXDemodInstance_t demod,
6385 DRXConstellation_t constellation, u32_t symbolRate)
6386 {
6387 pI2CDeviceAddr_t devAddr = NULL; /* device address for I2C writes */
6388 pDRXJData_t extAttr = NULL; /* Global data container for DRXJ specif data */
6389 u32_t fecBitsDesired = 0; /* BER accounting period */
6390 u16_t fecRsPlen = 0; /* defines RS BER measurement period */
6391 u16_t fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
6392 u32_t fecRsPeriod = 0; /* Value for corresponding I2C register */
6393 u32_t fecRsBitCnt = 0; /* Actual precise amount of bits */
6394 u32_t fecOcSncFailPeriod = 0; /* Value for corresponding I2C register */
6395 u32_t qamVdPeriod = 0; /* Value for corresponding I2C register */
6396 u32_t qamVdBitCnt = 0; /* Actual precise amount of bits */
6397 u16_t fecVdPlen = 0; /* no of trellis symbols: VD SER measur period */
6398 u16_t qamVdPrescale = 0; /* Viterbi Measurement Prescale */
6399
6400 devAddr = demod->myI2CDevAddr;
6401 extAttr = (pDRXJData_t) demod->myExtAttr;
6402
6403 fecBitsDesired = extAttr->fecBitsDesired;
6404 fecRsPrescale = extAttr->fecRsPrescale;
6405
6406 switch (constellation) {
6407 case DRX_CONSTELLATION_QAM16:
6408 fecBitsDesired = 4 * symbolRate;
6409 break;
6410 case DRX_CONSTELLATION_QAM32:
6411 fecBitsDesired = 5 * symbolRate;
6412 break;
6413 case DRX_CONSTELLATION_QAM64:
6414 fecBitsDesired = 6 * symbolRate;
6415 break;
6416 case DRX_CONSTELLATION_QAM128:
6417 fecBitsDesired = 7 * symbolRate;
6418 break;
6419 case DRX_CONSTELLATION_QAM256:
6420 fecBitsDesired = 8 * symbolRate;
6421 break;
6422 default:
6423 return (DRX_STS_INVALID_ARG);
6424 }
6425
6426 /* Parameters for Reed-Solomon Decoder */
6427 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6428 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6429 /* result is within 32 bit arithmetic -> */
6430 /* no need for mult or frac functions */
6431
6432 /* TODO: use constant instead of calculation and remove the fecRsPlen in extAttr */
6433 switch (extAttr->standard) {
6434 case DRX_STANDARD_ITU_A:
6435 case DRX_STANDARD_ITU_C:
6436 fecRsPlen = 204 * 8;
6437 break;
6438 case DRX_STANDARD_ITU_B:
6439 fecRsPlen = 128 * 7;
6440 break;
6441 default:
6442 return (DRX_STS_INVALID_ARG);
6443 }
6444
6445 extAttr->fecRsPlen = fecRsPlen; /* for getSigQual */
6446 fecRsBitCnt = fecRsPrescale * fecRsPlen; /* temp storage */
6447 CHK_ZERO(fecRsBitCnt);
6448 fecRsPeriod = fecBitsDesired / fecRsBitCnt + 1; /* ceil */
6449 if (extAttr->standard != DRX_STANDARD_ITU_B)
6450 fecOcSncFailPeriod = fecRsPeriod;
6451
6452 /* limit to max 16 bit value (I2C register width) if needed */
6453 if (fecRsPeriod > 0xFFFF)
6454 fecRsPeriod = 0xFFFF;
6455
6456 /* write corresponding registers */
6457 switch (extAttr->standard) {
6458 case DRX_STANDARD_ITU_A:
6459 case DRX_STANDARD_ITU_C:
6460 break;
6461 case DRX_STANDARD_ITU_B:
6462 switch (constellation) {
6463 case DRX_CONSTELLATION_QAM64:
6464 fecRsPeriod = 31581;
6465 fecOcSncFailPeriod = 17932;
6466 break;
6467 case DRX_CONSTELLATION_QAM256:
6468 fecRsPeriod = 45446;
6469 fecOcSncFailPeriod = 25805;
6470 break;
6471 default:
6472 return (DRX_STS_INVALID_ARG);
6473 }
6474 break;
6475 default:
6476 return (DRX_STS_INVALID_ARG);
6477 }
6478
6479 WR16(devAddr, FEC_OC_SNC_FAIL_PERIOD__A, (u16_t) fecOcSncFailPeriod);
6480 WR16(devAddr, FEC_RS_MEASUREMENT_PERIOD__A, (u16_t) fecRsPeriod);
6481 WR16(devAddr, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
6482 extAttr->fecRsPeriod = (u16_t) fecRsPeriod;
6483 extAttr->fecRsPrescale = fecRsPrescale;
6484 WR32(devAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0);
6485 WR16(devAddr, SCU_RAM_FEC_MEAS_COUNT__A, 0);
6486 WR16(devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
6487
6488 if (extAttr->standard == DRX_STANDARD_ITU_B) {
6489 /* Parameters for Viterbi Decoder */
6490 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6491 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6492 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6493 /* result is within 32 bit arithmetic -> */
6494 /* no need for mult or frac functions */
6495
6496 /* a(8 bit) * b(8 bit) = 16 bit result => Mult32 not needed */
6497 fecVdPlen = extAttr->fecVdPlen;
6498 qamVdPrescale = extAttr->qamVdPrescale;
6499 qamVdBitCnt = qamVdPrescale * fecVdPlen; /* temp storage */
6500
6501 switch (constellation) {
6502 case DRX_CONSTELLATION_QAM64:
6503 /* a(16 bit) * b(4 bit) = 20 bit result => Mult32 not needed */
6504 qamVdPeriod =
6505 qamVdBitCnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
6506 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6507 break;
6508 case DRX_CONSTELLATION_QAM256:
6509 /* a(16 bit) * b(5 bit) = 21 bit result => Mult32 not needed */
6510 qamVdPeriod =
6511 qamVdBitCnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
6512 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6513 break;
6514 default:
6515 return (DRX_STS_INVALID_ARG);
6516 }
6517 CHK_ZERO(qamVdPeriod);
6518 qamVdPeriod = fecBitsDesired / qamVdPeriod;
6519 /* limit to max 16 bit value (I2C register width) if needed */
6520 if (qamVdPeriod > 0xFFFF)
6521 qamVdPeriod = 0xFFFF;
6522
6523 /* a(16 bit) * b(16 bit) = 32 bit result => Mult32 not needed */
6524 qamVdBitCnt *= qamVdPeriod;
6525
6526 WR16(devAddr, QAM_VD_MEASUREMENT_PERIOD__A,
6527 (u16_t) qamVdPeriod);
6528 WR16(devAddr, QAM_VD_MEASUREMENT_PRESCALE__A, qamVdPrescale);
6529 extAttr->qamVdPeriod = (u16_t) qamVdPeriod;
6530 extAttr->qamVdPrescale = qamVdPrescale;
6531 }
6532
6533 return (DRX_STS_OK);
6534 rw_error:
6535 return (DRX_STS_ERROR);
6536 }
6537
6538 /*============================================================================*/
6539
6540 /**
6541 * \fn DRXStatus_t SetQAM16 ()
6542 * \brief QAM16 specific setup
6543 * \param demod instance of demod.
6544 * \return DRXStatus_t.
6545 */
6546 static DRXStatus_t SetQAM16(pDRXDemodInstance_t demod)
6547 {
6548 pI2CDeviceAddr_t devAddr = demod->myI2CDevAddr;
6549 const u8_t qamDqQualFun[] = {
6550 DRXJ_16TO8(2), /* fun0 */
6551 DRXJ_16TO8(2), /* fun1 */
6552 DRXJ_16TO8(2), /* fun2 */
6553 DRXJ_16TO8(2), /* fun3 */
6554 DRXJ_16TO8(3), /* fun4 */
6555 DRXJ_16TO8(3), /* fun5 */
6556 };
6557 const u8_t qamEqCmaRad[] = {
6558 DRXJ_16TO8(13517), /* RAD0 */
6559 DRXJ_16TO8(13517), /* RAD1 */
6560 DRXJ_16TO8(13517), /* RAD2 */
6561 DRXJ_16TO8(13517), /* RAD3 */
6562 DRXJ_16TO8(13517), /* RAD4 */
6563 DRXJ_16TO8(13517), /* RAD5 */
6564 };
6565
6566 WRB(devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun),
6567 ((pu8_t) qamDqQualFun));
6568 WRB(devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad),
6569 ((pu8_t) qamEqCmaRad));
6570
6571 WR16(devAddr, SCU_RAM_QAM_FSM_RTH__A, 140);
6572 WR16(devAddr, SCU_RAM_QAM_FSM_FTH__A, 50);
6573 WR16(devAddr, SCU_RAM_QAM_FSM_PTH__A, 120);
6574 WR16(devAddr, SCU_RAM_QAM_FSM_QTH__A, 230);
6575 WR16(devAddr, SCU_RAM_QAM_FSM_CTH__A, 95);
6576 WR16(devAddr, SCU_RAM_QAM_FSM_MTH__A, 105);
6577
6578 WR16(devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6579 WR16(devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
6580 WR16(devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
6581
6582 WR16(devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16);
6583 WR16(devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220);
6584 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25);
6585 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6);
6586 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t) (-24));
6587 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t) (-65));
6588 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t) (-127));
6589
6590 WR16(devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6591 WR16(devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6592 WR16(devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6593 WR16(devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
6594 WR16(devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6595 WR16(devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6596 WR16(devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
6597 WR16(devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
6598 WR16(devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6599 WR16(devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6600 WR16(devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6601 WR16(devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6602 WR16(devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6603 WR16(devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6604 WR16(devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6605 WR16(devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6606 WR16(devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 240);
6607 WR16(devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6608 WR16(devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6609 WR16(devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
6610
6611 WR16(devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960);
6612
6613 return (DRX_STS_OK);
6614 rw_error:
6615 return (DRX_STS_ERROR);
6616 }
6617
6618 /*============================================================================*/
6619
6620 /**
6621 * \fn DRXStatus_t SetQAM32 ()
6622 * \brief QAM32 specific setup
6623 * \param demod instance of demod.
6624 * \return DRXStatus_t.
6625 */
6626 static DRXStatus_t SetQAM32(pDRXDemodInstance_t demod)
6627 {
6628 pI2CDeviceAddr_t devAddr = demod->myI2CDevAddr;
6629 const u8_t qamDqQualFun[] = {
6630 DRXJ_16TO8(3), /* fun0 */
6631 DRXJ_16TO8(3), /* fun1 */
6632 DRXJ_16TO8(3), /* fun2 */
6633 DRXJ_16TO8(3), /* fun3 */
6634 DRXJ_16TO8(4), /* fun4 */
6635 DRXJ_16TO8(4), /* fun5 */
6636 };
6637 const u8_t qamEqCmaRad[] = {
6638 DRXJ_16TO8(6707), /* RAD0 */
6639 DRXJ_16TO8(6707), /* RAD1 */
6640 DRXJ_16TO8(6707), /* RAD2 */
6641 DRXJ_16TO8(6707), /* RAD3 */
6642 DRXJ_16TO8(6707), /* RAD4 */
6643 DRXJ_16TO8(6707), /* RAD5 */
6644 };
6645
6646 WRB(devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun),
6647 ((pu8_t) qamDqQualFun));
6648 WRB(devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad),
6649 ((pu8_t) qamEqCmaRad));
6650
6651 WR16(devAddr, SCU_RAM_QAM_FSM_RTH__A, 90);
6652 WR16(devAddr, SCU_RAM_QAM_FSM_FTH__A, 50);
6653 WR16(devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
6654 WR16(devAddr, SCU_RAM_QAM_FSM_QTH__A, 170);
6655 WR16(devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
6656 WR16(devAddr, SCU_RAM_QAM_FSM_MTH__A, 100);
6657
6658 WR16(devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6659 WR16(devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
6660 WR16(devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
6661
6662 WR16(devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12);
6663 WR16(devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140);
6664 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16_t) (-8));
6665 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16_t) (-16));
6666 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t) (-26));
6667 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t) (-56));
6668 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t) (-86));
6669
6670 WR16(devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6671 WR16(devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6672 WR16(devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6673 WR16(devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
6674 WR16(devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6675 WR16(devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6676 WR16(devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
6677 WR16(devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
6678 WR16(devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6679 WR16(devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6680 WR16(devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6681 WR16(devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6682 WR16(devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6683 WR16(devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6684 WR16(devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6685 WR16(devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6686 WR16(devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 176);
6687 WR16(devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6688 WR16(devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6689 WR16(devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8);
6690
6691 WR16(devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480);
6692
6693 return (DRX_STS_OK);
6694 rw_error:
6695 return (DRX_STS_ERROR);
6696 }
6697
6698 /*============================================================================*/
6699
6700 /**
6701 * \fn DRXStatus_t SetQAM64 ()
6702 * \brief QAM64 specific setup
6703 * \param demod instance of demod.
6704 * \return DRXStatus_t.
6705 */
6706 static DRXStatus_t SetQAM64(pDRXDemodInstance_t demod)
6707 {
6708 pI2CDeviceAddr_t devAddr = demod->myI2CDevAddr;
6709 const u8_t qamDqQualFun[] = { /* this is hw reset value. no necessary to re-write */
6710 DRXJ_16TO8(4), /* fun0 */
6711 DRXJ_16TO8(4), /* fun1 */
6712 DRXJ_16TO8(4), /* fun2 */
6713 DRXJ_16TO8(4), /* fun3 */
6714 DRXJ_16TO8(6), /* fun4 */
6715 DRXJ_16TO8(6), /* fun5 */
6716 };
6717 const u8_t qamEqCmaRad[] = {
6718 DRXJ_16TO8(13336), /* RAD0 */
6719 DRXJ_16TO8(12618), /* RAD1 */
6720 DRXJ_16TO8(11988), /* RAD2 */
6721 DRXJ_16TO8(13809), /* RAD3 */
6722 DRXJ_16TO8(13809), /* RAD4 */
6723 DRXJ_16TO8(15609), /* RAD5 */
6724 };
6725
6726 WRB(devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun),
6727 ((pu8_t) qamDqQualFun));
6728 WRB(devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad),
6729 ((pu8_t) qamEqCmaRad));
6730
6731 WR16(devAddr, SCU_RAM_QAM_FSM_RTH__A, 105);
6732 WR16(devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
6733 WR16(devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
6734 WR16(devAddr, SCU_RAM_QAM_FSM_QTH__A, 195);
6735 WR16(devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
6736 WR16(devAddr, SCU_RAM_QAM_FSM_MTH__A, 84);
6737
6738 WR16(devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6739 WR16(devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
6740 WR16(devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
6741
6742 WR16(devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12);
6743 WR16(devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141);
6744 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7);
6745 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0);
6746 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t) (-15));
6747 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t) (-45));
6748 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t) (-80));
6749
6750 WR16(devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6751 WR16(devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6752 WR16(devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6753 WR16(devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
6754 WR16(devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6755 WR16(devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6756 WR16(devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15);
6757 WR16(devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6758 WR16(devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6759 WR16(devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6760 WR16(devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6761 WR16(devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6762 WR16(devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6763 WR16(devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6764 WR16(devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6765 WR16(devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
6766 WR16(devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 160);
6767 WR16(devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6768 WR16(devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6769 WR16(devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
6770
6771 WR16(devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008);
6772
6773 return (DRX_STS_OK);
6774 rw_error:
6775 return (DRX_STS_ERROR);
6776 }
6777
6778 /*============================================================================*/
6779
6780 /**
6781 * \fn DRXStatus_t SetQAM128 ()
6782 * \brief QAM128 specific setup
6783 * \param demod: instance of demod.
6784 * \return DRXStatus_t.
6785 */
6786 static DRXStatus_t SetQAM128(pDRXDemodInstance_t demod)
6787 {
6788 pI2CDeviceAddr_t devAddr = demod->myI2CDevAddr;
6789 const u8_t qamDqQualFun[] = {
6790 DRXJ_16TO8(6), /* fun0 */
6791 DRXJ_16TO8(6), /* fun1 */
6792 DRXJ_16TO8(6), /* fun2 */
6793 DRXJ_16TO8(6), /* fun3 */
6794 DRXJ_16TO8(9), /* fun4 */
6795 DRXJ_16TO8(9), /* fun5 */
6796 };
6797 const u8_t qamEqCmaRad[] = {
6798 DRXJ_16TO8(6164), /* RAD0 */
6799 DRXJ_16TO8(6598), /* RAD1 */
6800 DRXJ_16TO8(6394), /* RAD2 */
6801 DRXJ_16TO8(6409), /* RAD3 */
6802 DRXJ_16TO8(6656), /* RAD4 */
6803 DRXJ_16TO8(7238), /* RAD5 */
6804 };
6805
6806 WRB(devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun),
6807 ((pu8_t) qamDqQualFun));
6808 WRB(devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad),
6809 ((pu8_t) qamEqCmaRad));
6810
6811 WR16(devAddr, SCU_RAM_QAM_FSM_RTH__A, 50);
6812 WR16(devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
6813 WR16(devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
6814 WR16(devAddr, SCU_RAM_QAM_FSM_QTH__A, 140);
6815 WR16(devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
6816 WR16(devAddr, SCU_RAM_QAM_FSM_MTH__A, 100);
6817
6818 WR16(devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6819 WR16(devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
6820 WR16(devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
6821
6822 WR16(devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8);
6823 WR16(devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65);
6824 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5);
6825 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3);
6826 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t) (-1));
6827 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12);
6828 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t) (-23));
6829
6830 WR16(devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6831 WR16(devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6832 WR16(devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6833 WR16(devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
6834 WR16(devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6835 WR16(devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6836 WR16(devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
6837 WR16(devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6838 WR16(devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6839 WR16(devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6840 WR16(devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6841 WR16(devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6842 WR16(devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6843 WR16(devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6844 WR16(devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6845 WR16(devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6846 WR16(devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 144);
6847 WR16(devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6848 WR16(devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6849 WR16(devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
6850
6851 WR16(devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992);
6852
6853 return (DRX_STS_OK);
6854 rw_error:
6855 return (DRX_STS_ERROR);
6856 }
6857
6858 /*============================================================================*/
6859
6860 /**
6861 * \fn DRXStatus_t SetQAM256 ()
6862 * \brief QAM256 specific setup
6863 * \param demod: instance of demod.
6864 * \return DRXStatus_t.
6865 */
6866 static DRXStatus_t SetQAM256(pDRXDemodInstance_t demod)
6867 {
6868 pI2CDeviceAddr_t devAddr = demod->myI2CDevAddr;
6869 const u8_t qamDqQualFun[] = {
6870 DRXJ_16TO8(8), /* fun0 */
6871 DRXJ_16TO8(8), /* fun1 */
6872 DRXJ_16TO8(8), /* fun2 */
6873 DRXJ_16TO8(8), /* fun3 */
6874 DRXJ_16TO8(12), /* fun4 */
6875 DRXJ_16TO8(12), /* fun5 */
6876 };
6877 const u8_t qamEqCmaRad[] = {
6878 DRXJ_16TO8(12345), /* RAD0 */
6879 DRXJ_16TO8(12345), /* RAD1 */
6880 DRXJ_16TO8(13626), /* RAD2 */
6881 DRXJ_16TO8(12931), /* RAD3 */
6882 DRXJ_16TO8(14719), /* RAD4 */
6883 DRXJ_16TO8(15356), /* RAD5 */
6884 };
6885
6886 WRB(devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun),
6887 ((pu8_t) qamDqQualFun));
6888 WRB(devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad),
6889 ((pu8_t) qamEqCmaRad));
6890
6891 WR16(devAddr, SCU_RAM_QAM_FSM_RTH__A, 50);
6892 WR16(devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
6893 WR16(devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
6894 WR16(devAddr, SCU_RAM_QAM_FSM_QTH__A, 150);
6895 WR16(devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
6896 WR16(devAddr, SCU_RAM_QAM_FSM_MTH__A, 110);
6897
6898 WR16(devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6899 WR16(devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16);
6900 WR16(devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
6901
6902 WR16(devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8);
6903 WR16(devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74);
6904 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18);
6905 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13);
6906 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7);
6907 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0);
6908 WR16(devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t) (-8));
6909
6910 WR16(devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6911 WR16(devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6912 WR16(devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6913 WR16(devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
6914 WR16(devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6915 WR16(devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6916 WR16(devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25);
6917 WR16(devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6918 WR16(devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6919 WR16(devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6920 WR16(devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6921 WR16(devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6922 WR16(devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6923 WR16(devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6924 WR16(devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6925 WR16(devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
6926 WR16(devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 80);
6927 WR16(devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6928 WR16(devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6929 WR16(devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
6930
6931 WR16(devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520);
6932
6933 return (DRX_STS_OK);
6934 rw_error:
6935 return (DRX_STS_ERROR);
6936 }
6937
6938 /*============================================================================*/
6939 #define QAM_SET_OP_ALL 0x1
6940 #define QAM_SET_OP_CONSTELLATION 0x2
6941 #define QAM_SET_OP_SPECTRUM 0X4
6942
6943 /**
6944 * \fn DRXStatus_t SetQAM ()
6945 * \brief Set QAM demod.
6946 * \param demod: instance of demod.
6947 * \param channel: pointer to channel data.
6948 * \return DRXStatus_t.
6949 */
6950 static DRXStatus_t
6951 SetQAM(pDRXDemodInstance_t demod,
6952 pDRXChannel_t channel, DRXFrequency_t tunerFreqOffset, u32_t op)
6953 {
6954 pI2CDeviceAddr_t devAddr = NULL;
6955 pDRXJData_t extAttr = NULL;
6956 pDRXCommonAttr_t commonAttr = NULL;
6957 u16_t cmdResult = 0;
6958 u32_t adcFrequency = 0;
6959 u32_t iqmRcRate = 0;
6960 u16_t lcSymbolFreq = 0;
6961 u16_t iqmRcStretch = 0;
6962 u16_t setEnvParameters = 0;
6963 u16_t setParamParameters[2] = { 0 };
6964 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
6965 /* parameterLen */ 0,
6966 /* resultLen */ 0,
6967 /* parameter */ NULL,
6968 /* result */ NULL
6969 };
6970 const u8_t qamA_taps[] = {
6971 DRXJ_16TO8(-1), /* re0 */
6972 DRXJ_16TO8(1), /* re1 */
6973 DRXJ_16TO8(1), /* re2 */
6974 DRXJ_16TO8(-1), /* re3 */
6975 DRXJ_16TO8(-1), /* re4 */
6976 DRXJ_16TO8(2), /* re5 */
6977 DRXJ_16TO8(1), /* re6 */
6978 DRXJ_16TO8(-2), /* re7 */
6979 DRXJ_16TO8(0), /* re8 */
6980 DRXJ_16TO8(3), /* re9 */
6981 DRXJ_16TO8(-1), /* re10 */
6982 DRXJ_16TO8(-3), /* re11 */
6983 DRXJ_16TO8(4), /* re12 */
6984 DRXJ_16TO8(1), /* re13 */
6985 DRXJ_16TO8(-8), /* re14 */
6986 DRXJ_16TO8(4), /* re15 */
6987 DRXJ_16TO8(13), /* re16 */
6988 DRXJ_16TO8(-13), /* re17 */
6989 DRXJ_16TO8(-19), /* re18 */
6990 DRXJ_16TO8(28), /* re19 */
6991 DRXJ_16TO8(25), /* re20 */
6992 DRXJ_16TO8(-53), /* re21 */
6993 DRXJ_16TO8(-31), /* re22 */
6994 DRXJ_16TO8(96), /* re23 */
6995 DRXJ_16TO8(37), /* re24 */
6996 DRXJ_16TO8(-190), /* re25 */
6997 DRXJ_16TO8(-40), /* re26 */
6998 DRXJ_16TO8(619) /* re27 */
6999 };
7000 const u8_t qamB64_taps[] = {
7001 DRXJ_16TO8(0), /* re0 */
7002 DRXJ_16TO8(-2), /* re1 */
7003 DRXJ_16TO8(1), /* re2 */
7004 DRXJ_16TO8(2), /* re3 */
7005 DRXJ_16TO8(-2), /* re4 */
7006 DRXJ_16TO8(0), /* re5 */
7007 DRXJ_16TO8(4), /* re6 */
7008 DRXJ_16TO8(-2), /* re7 */
7009 DRXJ_16TO8(-4), /* re8 */
7010 DRXJ_16TO8(4), /* re9 */
7011 DRXJ_16TO8(3), /* re10 */
7012 DRXJ_16TO8(-6), /* re11 */
7013 DRXJ_16TO8(0), /* re12 */
7014 DRXJ_16TO8(6), /* re13 */
7015 DRXJ_16TO8(-5), /* re14 */
7016 DRXJ_16TO8(-3), /* re15 */
7017 DRXJ_16TO8(11), /* re16 */
7018 DRXJ_16TO8(-4), /* re17 */
7019 DRXJ_16TO8(-19), /* re18 */
7020 DRXJ_16TO8(19), /* re19 */
7021 DRXJ_16TO8(28), /* re20 */
7022 DRXJ_16TO8(-45), /* re21 */
7023 DRXJ_16TO8(-36), /* re22 */
7024 DRXJ_16TO8(90), /* re23 */
7025 DRXJ_16TO8(42), /* re24 */
7026 DRXJ_16TO8(-185), /* re25 */
7027 DRXJ_16TO8(-46), /* re26 */
7028 DRXJ_16TO8(614) /* re27 */
7029 };
7030 const u8_t qamB256_taps[] = {
7031 DRXJ_16TO8(-2), /* re0 */
7032 DRXJ_16TO8(4), /* re1 */
7033 DRXJ_16TO8(1), /* re2 */
7034 DRXJ_16TO8(-4), /* re3 */
7035 DRXJ_16TO8(0), /* re4 */
7036 DRXJ_16TO8(4), /* re5 */
7037 DRXJ_16TO8(-2), /* re6 */
7038 DRXJ_16TO8(-4), /* re7 */
7039 DRXJ_16TO8(5), /* re8 */
7040 DRXJ_16TO8(2), /* re9 */
7041 DRXJ_16TO8(-8), /* re10 */
7042 DRXJ_16TO8(2), /* re11 */
7043 DRXJ_16TO8(11), /* re12 */
7044 DRXJ_16TO8(-8), /* re13 */
7045 DRXJ_16TO8(-15), /* re14 */
7046 DRXJ_16TO8(16), /* re15 */
7047 DRXJ_16TO8(19), /* re16 */
7048 DRXJ_16TO8(-27), /* re17 */
7049 DRXJ_16TO8(-22), /* re18 */
7050 DRXJ_16TO8(44), /* re19 */
7051 DRXJ_16TO8(26), /* re20 */
7052 DRXJ_16TO8(-69), /* re21 */
7053 DRXJ_16TO8(-28), /* re22 */
7054 DRXJ_16TO8(110), /* re23 */
7055 DRXJ_16TO8(31), /* re24 */
7056 DRXJ_16TO8(-201), /* re25 */
7057 DRXJ_16TO8(-32), /* re26 */
7058 DRXJ_16TO8(628) /* re27 */
7059 };
7060 const u8_t qamC_taps[] = {
7061 DRXJ_16TO8(-3), /* re0 */
7062 DRXJ_16TO8(3), /* re1 */
7063 DRXJ_16TO8(2), /* re2 */
7064 DRXJ_16TO8(-4), /* re3 */
7065 DRXJ_16TO8(0), /* re4 */
7066 DRXJ_16TO8(4), /* re5 */
7067 DRXJ_16TO8(-1), /* re6 */
7068 DRXJ_16TO8(-4), /* re7 */
7069 DRXJ_16TO8(3), /* re8 */
7070 DRXJ_16TO8(3), /* re9 */
7071 DRXJ_16TO8(-5), /* re10 */
7072 DRXJ_16TO8(0), /* re11 */
7073 DRXJ_16TO8(9), /* re12 */
7074 DRXJ_16TO8(-4), /* re13 */
7075 DRXJ_16TO8(-12), /* re14 */
7076 DRXJ_16TO8(10), /* re15 */
7077 DRXJ_16TO8(16), /* re16 */
7078 DRXJ_16TO8(-21), /* re17 */
7079 DRXJ_16TO8(-20), /* re18 */
7080 DRXJ_16TO8(37), /* re19 */
7081 DRXJ_16TO8(25), /* re20 */
7082 DRXJ_16TO8(-62), /* re21 */
7083 DRXJ_16TO8(-28), /* re22 */
7084 DRXJ_16TO8(105), /* re23 */
7085 DRXJ_16TO8(31), /* re24 */
7086 DRXJ_16TO8(-197), /* re25 */
7087 DRXJ_16TO8(-33), /* re26 */
7088 DRXJ_16TO8(626) /* re27 */
7089 };
7090
7091 devAddr = demod->myI2CDevAddr;
7092 extAttr = (pDRXJData_t) demod->myExtAttr;
7093 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
7094
7095 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7096 if (extAttr->standard == DRX_STANDARD_ITU_B) {
7097 switch (channel->constellation) {
7098 case DRX_CONSTELLATION_QAM256:
7099 iqmRcRate = 0x00AE3562;
7100 lcSymbolFreq =
7101 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
7102 channel->symbolrate = 5360537;
7103 iqmRcStretch = IQM_RC_STRETCH_QAM_B_256;
7104 break;
7105 case DRX_CONSTELLATION_QAM64:
7106 iqmRcRate = 0x00C05A0E;
7107 lcSymbolFreq = 409;
7108 channel->symbolrate = 5056941;
7109 iqmRcStretch = IQM_RC_STRETCH_QAM_B_64;
7110 break;
7111 default:
7112 return (DRX_STS_INVALID_ARG);
7113 }
7114 } else {
7115 adcFrequency = (commonAttr->sysClockFreq * 1000) / 3;
7116 CHK_ZERO(channel->symbolrate);
7117 iqmRcRate =
7118 (adcFrequency / channel->symbolrate) * (1 << 21) +
7119 (Frac28
7120 ((adcFrequency % channel->symbolrate),
7121 channel->symbolrate) >> 7) - (1 << 23);
7122 lcSymbolFreq =
7123 (u16_t) (Frac28
7124 (channel->symbolrate +
7125 (adcFrequency >> 13),
7126 adcFrequency) >> 16);
7127 if (lcSymbolFreq > 511)
7128 lcSymbolFreq = 511;
7129
7130 iqmRcStretch = 21;
7131 }
7132
7133 if (extAttr->standard == DRX_STANDARD_ITU_A) {
7134 setEnvParameters = QAM_TOP_ANNEX_A; /* annex */
7135 setParamParameters[0] = channel->constellation; /* constellation */
7136 setParamParameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
7137 } else if (extAttr->standard == DRX_STANDARD_ITU_B) {
7138 setEnvParameters = QAM_TOP_ANNEX_B; /* annex */
7139 setParamParameters[0] = channel->constellation; /* constellation */
7140 setParamParameters[1] = channel->interleavemode; /* interleave mode */
7141 } else if (extAttr->standard == DRX_STANDARD_ITU_C) {
7142 setEnvParameters = QAM_TOP_ANNEX_C; /* annex */
7143 setParamParameters[0] = channel->constellation; /* constellation */
7144 setParamParameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
7145 } else {
7146 return (DRX_STS_INVALID_ARG);
7147 }
7148 }
7149
7150 if (op & QAM_SET_OP_ALL) {
7151 /*
7152 STEP 1: reset demodulator
7153 resets IQM, QAM and FEC HW blocks
7154 resets SCU variables
7155 */
7156 /* stop all comm_exec */
7157 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
7158 WR16(devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
7159 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
7160 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
7161 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
7162 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
7163 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
7164
7165 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
7166 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
7167 cmdSCU.parameterLen = 0;
7168 cmdSCU.resultLen = 1;
7169 cmdSCU.parameter = NULL;
7170 cmdSCU.result = &cmdResult;
7171 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
7172 }
7173
7174 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7175 /*
7176 STEP 2: configure demodulator
7177 -set env
7178 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
7179 */
7180 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
7181 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
7182 cmdSCU.parameterLen = 1;
7183 cmdSCU.resultLen = 1;
7184 cmdSCU.parameter = &setEnvParameters;
7185 cmdSCU.result = &cmdResult;
7186 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
7187
7188 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
7189 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
7190 cmdSCU.parameterLen = 2;
7191 cmdSCU.resultLen = 1;
7192 cmdSCU.parameter = setParamParameters;
7193 cmdSCU.result = &cmdResult;
7194 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
7195 /* set symbol rate */
7196 WR32(devAddr, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
7197 extAttr->iqmRcRateOfs = iqmRcRate;
7198 CHK_ERROR(SetQAMMeasurement
7199 (demod, channel->constellation, channel->symbolrate));
7200 }
7201 /* STEP 3: enable the system in a mode where the ADC provides valid signal
7202 setup constellation independent registers */
7203 /* from qam_cmd.py script (qam_driver_b) */
7204 /* TODO: remove re-writes of HW reset values */
7205 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
7206 CHK_ERROR(SetFrequency(demod, channel, tunerFreqOffset));
7207 }
7208
7209 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7210
7211 WR16(devAddr, QAM_LC_SYMBOL_FREQ__A, lcSymbolFreq);
7212 WR16(devAddr, IQM_RC_STRETCH__A, iqmRcStretch);
7213 }
7214
7215 if (op & QAM_SET_OP_ALL) {
7216 if (extAttr->hasLNA == FALSE) {
7217 WR16(devAddr, IQM_AF_AMUX__A, 0x02);
7218 }
7219 WR16(devAddr, IQM_CF_SYMMETRIC__A, 0);
7220 WR16(devAddr, IQM_CF_MIDTAP__A, 3);
7221 WR16(devAddr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M);
7222
7223 WR16(devAddr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f); /* scu temporary shut down agc */
7224
7225 WR16(devAddr, IQM_AF_SYNC_SEL__A, 3);
7226 WR16(devAddr, IQM_AF_CLP_LEN__A, 0);
7227 WR16(devAddr, IQM_AF_CLP_TH__A, 448);
7228 WR16(devAddr, IQM_AF_SNS_LEN__A, 0);
7229 WR16(devAddr, IQM_AF_PDREF__A, 4);
7230 WR16(devAddr, IQM_AF_STDBY__A, 0x10);
7231 WR16(devAddr, IQM_AF_PGA_GAIN__A, 11);
7232
7233 WR16(devAddr, IQM_CF_POW_MEAS_LEN__A, 1);
7234 WR16(devAddr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); /*! reset default val ! */
7235
7236 WR16(devAddr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); /*! reset default val ! */
7237 if (extAttr->standard == DRX_STANDARD_ITU_B) {
7238 WR16(devAddr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE); /*! reset default val ! */
7239 WR16(devAddr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE); /*! reset default val ! */
7240 WR16(devAddr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
7241 } else {
7242 switch (channel->constellation) {
7243 case DRX_CONSTELLATION_QAM16:
7244 case DRX_CONSTELLATION_QAM64:
7245 case DRX_CONSTELLATION_QAM256:
7246 WR16(devAddr, QAM_SY_SYNC_LWM__A, 0x03);
7247 WR16(devAddr, QAM_SY_SYNC_AWM__A, 0x04);
7248 WR16(devAddr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
7249 break;
7250 case DRX_CONSTELLATION_QAM32:
7251 case DRX_CONSTELLATION_QAM128:
7252 WR16(devAddr, QAM_SY_SYNC_LWM__A, 0x03);
7253 WR16(devAddr, QAM_SY_SYNC_AWM__A, 0x05);
7254 WR16(devAddr, QAM_SY_SYNC_HWM__A, 0x06);
7255 break;
7256 default:
7257 return (DRX_STS_ERROR);
7258 } /* switch */
7259 }
7260
7261 WR16(devAddr, QAM_LC_MODE__A, QAM_LC_MODE__PRE); /*! reset default val ! */
7262 WR16(devAddr, QAM_LC_RATE_LIMIT__A, 3);
7263 WR16(devAddr, QAM_LC_LPF_FACTORP__A, 4);
7264 WR16(devAddr, QAM_LC_LPF_FACTORI__A, 4);
7265 WR16(devAddr, QAM_LC_MODE__A, 7);
7266 WR16(devAddr, QAM_LC_QUAL_TAB0__A, 1);
7267 WR16(devAddr, QAM_LC_QUAL_TAB1__A, 1);
7268 WR16(devAddr, QAM_LC_QUAL_TAB2__A, 1);
7269 WR16(devAddr, QAM_LC_QUAL_TAB3__A, 1);
7270 WR16(devAddr, QAM_LC_QUAL_TAB4__A, 2);
7271 WR16(devAddr, QAM_LC_QUAL_TAB5__A, 2);
7272 WR16(devAddr, QAM_LC_QUAL_TAB6__A, 2);
7273 WR16(devAddr, QAM_LC_QUAL_TAB8__A, 2);
7274 WR16(devAddr, QAM_LC_QUAL_TAB9__A, 2);
7275 WR16(devAddr, QAM_LC_QUAL_TAB10__A, 2);
7276 WR16(devAddr, QAM_LC_QUAL_TAB12__A, 2);
7277 WR16(devAddr, QAM_LC_QUAL_TAB15__A, 3);
7278 WR16(devAddr, QAM_LC_QUAL_TAB16__A, 3);
7279 WR16(devAddr, QAM_LC_QUAL_TAB20__A, 4);
7280 WR16(devAddr, QAM_LC_QUAL_TAB25__A, 4);
7281
7282 WR16(devAddr, IQM_FS_ADJ_SEL__A, 1);
7283 WR16(devAddr, IQM_RC_ADJ_SEL__A, 1);
7284 WR16(devAddr, IQM_CF_ADJ_SEL__A, 1);
7285 WR16(devAddr, IQM_CF_POW_MEAS_LEN__A, 0);
7286 WR16(devAddr, SCU_RAM_GPIO__A, 0);
7287
7288 /* No more resets of the IQM, current standard correctly set =>
7289 now AGCs can be configured. */
7290 /* turn on IQMAF. It has to be in front of setAgc**() */
7291 CHK_ERROR(SetIqmAf(demod, TRUE));
7292 CHK_ERROR(ADCSynchronization(demod));
7293
7294 CHK_ERROR(InitAGC(demod));
7295 CHK_ERROR(SetAgcIf(demod, &(extAttr->qamIfAgcCfg), FALSE));
7296 CHK_ERROR(SetAgcRf(demod, &(extAttr->qamRfAgcCfg), FALSE));
7297 {
7298 /* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
7299 of only the gain */
7300 DRXJCfgAfeGain_t qamPgaCfg = { DRX_STANDARD_ITU_B, 0 };
7301
7302 qamPgaCfg.gain = extAttr->qamPgaCfg;
7303 CHK_ERROR(CtrlSetCfgAfeGain(demod, &qamPgaCfg));
7304 }
7305 CHK_ERROR(CtrlSetCfgPreSaw(demod, &(extAttr->qamPreSawCfg)));
7306 }
7307
7308 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7309 if (extAttr->standard == DRX_STANDARD_ITU_A) {
7310 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(qamA_taps),
7311 ((pu8_t) qamA_taps));
7312 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(qamA_taps),
7313 ((pu8_t) qamA_taps));
7314 } else if (extAttr->standard == DRX_STANDARD_ITU_B) {
7315 switch (channel->constellation) {
7316 case DRX_CONSTELLATION_QAM64:
7317 WRB(devAddr, IQM_CF_TAP_RE0__A,
7318 sizeof(qamB64_taps), ((pu8_t) qamB64_taps));
7319 WRB(devAddr, IQM_CF_TAP_IM0__A,
7320 sizeof(qamB64_taps), ((pu8_t) qamB64_taps));
7321 break;
7322 case DRX_CONSTELLATION_QAM256:
7323 WRB(devAddr, IQM_CF_TAP_RE0__A,
7324 sizeof(qamB256_taps),
7325 ((pu8_t) qamB256_taps));
7326 WRB(devAddr, IQM_CF_TAP_IM0__A,
7327 sizeof(qamB256_taps),
7328 ((pu8_t) qamB256_taps));
7329 break;
7330 default:
7331 return (DRX_STS_ERROR);
7332 }
7333 } else if (extAttr->standard == DRX_STANDARD_ITU_C) {
7334 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(qamC_taps),
7335 ((pu8_t) qamC_taps));
7336 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(qamC_taps),
7337 ((pu8_t) qamC_taps));
7338 }
7339
7340 /* SETP 4: constellation specific setup */
7341 switch (channel->constellation) {
7342 case DRX_CONSTELLATION_QAM16:
7343 CHK_ERROR(SetQAM16(demod));
7344 break;
7345 case DRX_CONSTELLATION_QAM32:
7346 CHK_ERROR(SetQAM32(demod));
7347 break;
7348 case DRX_CONSTELLATION_QAM64:
7349 CHK_ERROR(SetQAM64(demod));
7350 break;
7351 case DRX_CONSTELLATION_QAM128:
7352 CHK_ERROR(SetQAM128(demod));
7353 break;
7354 case DRX_CONSTELLATION_QAM256:
7355 CHK_ERROR(SetQAM256(demod));
7356 break;
7357 default:
7358 return (DRX_STS_ERROR);
7359 } /* switch */
7360 }
7361
7362 if ((op & QAM_SET_OP_ALL)) {
7363 WR16(devAddr, IQM_CF_SCALE_SH__A, 0);
7364
7365 /* Mpeg output has to be in front of FEC active */
7366 CHK_ERROR(SetMPEGTEIHandling(demod));
7367 CHK_ERROR(BitReverseMPEGOutput(demod));
7368 CHK_ERROR(SetMPEGStartWidth(demod));
7369 {
7370 /* TODO: move to setStandard after hardware reset value problem is solved */
7371 /* Configure initial MPEG output */
7372 DRXCfgMPEGOutput_t cfgMPEGOutput;
7373
7374 cfgMPEGOutput.enableMPEGOutput = TRUE;
7375 cfgMPEGOutput.insertRSByte =
7376 commonAttr->mpegCfg.insertRSByte;
7377 cfgMPEGOutput.enableParallel =
7378 commonAttr->mpegCfg.enableParallel;
7379 cfgMPEGOutput.invertDATA =
7380 commonAttr->mpegCfg.invertDATA;
7381 cfgMPEGOutput.invertERR = commonAttr->mpegCfg.invertERR;
7382 cfgMPEGOutput.invertSTR = commonAttr->mpegCfg.invertSTR;
7383 cfgMPEGOutput.invertVAL = commonAttr->mpegCfg.invertVAL;
7384 cfgMPEGOutput.invertCLK = commonAttr->mpegCfg.invertCLK;
7385 cfgMPEGOutput.staticCLK = commonAttr->mpegCfg.staticCLK;
7386 cfgMPEGOutput.bitrate = commonAttr->mpegCfg.bitrate;
7387 CHK_ERROR(CtrlSetCfgMPEGOutput(demod, &cfgMPEGOutput));
7388 }
7389 }
7390
7391 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7392
7393 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
7394 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
7395 SCU_RAM_COMMAND_CMD_DEMOD_START;
7396 cmdSCU.parameterLen = 0;
7397 cmdSCU.resultLen = 1;
7398 cmdSCU.parameter = NULL;
7399 cmdSCU.result = &cmdResult;
7400 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
7401 }
7402
7403 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
7404 WR16(devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
7405 WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
7406
7407 return (DRX_STS_OK);
7408 rw_error:
7409 return (DRX_STS_ERROR);
7410 }
7411
7412 /*============================================================================*/
7413 static DRXStatus_t
7414 CtrlGetQAMSigQuality(pDRXDemodInstance_t demod, pDRXSigQuality_t sigQuality);
7415 static DRXStatus_t qamFlipSpec(pDRXDemodInstance_t demod, pDRXChannel_t channel)
7416 {
7417 u32_t iqmFsRateOfs = 0;
7418 u32_t iqmFsRateLo = 0;
7419 u16_t qamCtlEna = 0;
7420 u16_t data = 0;
7421 u16_t equMode = 0;
7422 u16_t fsmState = 0;
7423 int i = 0;
7424 int ofsofs = 0;
7425 pI2CDeviceAddr_t devAddr = NULL;
7426 pDRXJData_t extAttr = NULL;
7427
7428 devAddr = demod->myI2CDevAddr;
7429 extAttr = (pDRXJData_t) demod->myExtAttr;
7430
7431 /* Silence the controlling of lc, equ, and the acquisition state machine */
7432 RR16(devAddr, SCU_RAM_QAM_CTL_ENA__A, &qamCtlEna);
7433 WR16(devAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna
7434 & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M
7435 | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M));
7436
7437 /* freeze the frequency control loop */
7438 WR16(devAddr, QAM_LC_CF__A, 0);
7439 WR16(devAddr, QAM_LC_CF1__A, 0);
7440
7441 ARR32(devAddr, IQM_FS_RATE_OFS_LO__A, &iqmFsRateOfs);
7442 ARR32(devAddr, IQM_FS_RATE_LO__A, &iqmFsRateLo);
7443 ofsofs = iqmFsRateLo - iqmFsRateOfs;
7444 iqmFsRateOfs = ~iqmFsRateOfs + 1;
7445 iqmFsRateOfs -= 2 * ofsofs;
7446
7447 /* freeze dq/fq updating */
7448 RR16(devAddr, QAM_DQ_MODE__A, &data);
7449 data = (data & 0xfff9);
7450 WR16(devAddr, QAM_DQ_MODE__A, data);
7451 WR16(devAddr, QAM_FQ_MODE__A, data);
7452
7453 /* lc_cp / _ci / _ca */
7454 WR16(devAddr, QAM_LC_CI__A, 0);
7455 WR16(devAddr, QAM_LC_EP__A, 0);
7456 WR16(devAddr, QAM_FQ_LA_FACTOR__A, 0);
7457
7458 /* flip the spec */
7459 WR32(devAddr, IQM_FS_RATE_OFS_LO__A, iqmFsRateOfs);
7460 extAttr->iqmFsRateOfs = iqmFsRateOfs;
7461 extAttr->posImage = (extAttr->posImage) ? FALSE : TRUE;
7462
7463 /* freeze dq/fq updating */
7464 RR16(devAddr, QAM_DQ_MODE__A, &data);
7465 equMode = data;
7466 data = (data & 0xfff9);
7467 WR16(devAddr, QAM_DQ_MODE__A, data);
7468 WR16(devAddr, QAM_FQ_MODE__A, data);
7469
7470 for (i = 0; i < 28; i++) {
7471 RR16(devAddr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data);
7472 WR16(devAddr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data);
7473 }
7474
7475 for (i = 0; i < 24; i++) {
7476 RR16(devAddr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data);
7477 WR16(devAddr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data);
7478 }
7479
7480 data = equMode;
7481 WR16(devAddr, QAM_DQ_MODE__A, data);
7482 WR16(devAddr, QAM_FQ_MODE__A, data);
7483
7484 WR16(devAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4);
7485
7486 i = 0;
7487 while ((fsmState != 4) && (i++ < 100)) {
7488 RR16(devAddr, SCU_RAM_QAM_FSM_STATE__A, &fsmState);
7489 }
7490 WR16(devAddr, SCU_RAM_QAM_CTL_ENA__A, (qamCtlEna | 0x0016));
7491
7492 return (DRX_STS_OK);
7493 rw_error:
7494 return (DRX_STS_ERROR);
7495
7496 }
7497
7498 #define NO_LOCK 0x0
7499 #define DEMOD_LOCKED 0x1
7500 #define SYNC_FLIPPED 0x2
7501 #define SPEC_MIRRORED 0x4
7502 /**
7503 * \fn DRXStatus_t QAM64Auto ()
7504 * \brief auto do sync pattern switching and mirroring.
7505 * \param demod: instance of demod.
7506 * \param channel: pointer to channel data.
7507 * \param tunerFreqOffset: tuner frequency offset.
7508 * \param lockStatus: pointer to lock status.
7509 * \return DRXStatus_t.
7510 */
7511 static DRXStatus_t
7512 QAM64Auto(pDRXDemodInstance_t demod,
7513 pDRXChannel_t channel,
7514 DRXFrequency_t tunerFreqOffset, pDRXLockStatus_t lockStatus)
7515 {
7516 DRXSigQuality_t sigQuality;
7517 u16_t data = 0;
7518 u32_t state = NO_LOCK;
7519 u32_t startTime = 0;
7520 u32_t dLockedTime = 0;
7521 pDRXJData_t extAttr = NULL;
7522 u32_t timeoutOfs = 0;
7523
7524 /* external attributes for storing aquired channel constellation */
7525 extAttr = (pDRXJData_t) demod->myExtAttr;
7526 *lockStatus = DRX_NOT_LOCKED;
7527 startTime = DRXBSP_HST_Clock();
7528 state = NO_LOCK;
7529 do {
7530 CHK_ERROR(CtrlLockStatus(demod, lockStatus));
7531
7532 switch (state) {
7533 case NO_LOCK:
7534 if (*lockStatus == DRXJ_DEMOD_LOCK) {
7535 CHK_ERROR(CtrlGetQAMSigQuality
7536 (demod, &sigQuality));
7537 if (sigQuality.MER > 208) {
7538 state = DEMOD_LOCKED;
7539 /* some delay to see if fec_lock possible TODO find the right value */
7540 timeoutOfs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
7541 dLockedTime = DRXBSP_HST_Clock();
7542 }
7543 }
7544 break;
7545 case DEMOD_LOCKED:
7546 if ((*lockStatus == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
7547 ((DRXBSP_HST_Clock() - dLockedTime) >
7548 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
7549 RR16(demod->myI2CDevAddr, QAM_SY_TIMEOUT__A,
7550 &data);
7551 WR16(demod->myI2CDevAddr, QAM_SY_TIMEOUT__A,
7552 data | 0x1);
7553 state = SYNC_FLIPPED;
7554 DRXBSP_HST_Sleep(10);
7555 }
7556 break;
7557 case SYNC_FLIPPED:
7558 if (*lockStatus == DRXJ_DEMOD_LOCK) {
7559 if (channel->mirror == DRX_MIRROR_AUTO) {
7560 /* flip sync pattern back */
7561 RR16(demod->myI2CDevAddr,
7562 QAM_SY_TIMEOUT__A, &data);
7563 WR16(demod->myI2CDevAddr,
7564 QAM_SY_TIMEOUT__A, data & 0xFFFE);
7565 /* flip spectrum */
7566 extAttr->mirror = DRX_MIRROR_YES;
7567 CHK_ERROR(qamFlipSpec(demod, channel));
7568 state = SPEC_MIRRORED;
7569 /* reset timer TODO: still need 500ms? */
7570 startTime = dLockedTime =
7571 DRXBSP_HST_Clock();
7572 timeoutOfs = 0;
7573 } else { /* no need to wait lock */
7574
7575 startTime =
7576 DRXBSP_HST_Clock() -
7577 DRXJ_QAM_MAX_WAITTIME - timeoutOfs;
7578 }
7579 }
7580 break;
7581 case SPEC_MIRRORED:
7582 if ((*lockStatus == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
7583 ((DRXBSP_HST_Clock() - dLockedTime) >
7584 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
7585 CHK_ERROR(CtrlGetQAMSigQuality
7586 (demod, &sigQuality));
7587 if (sigQuality.MER > 208) {
7588 RR16(demod->myI2CDevAddr,
7589 QAM_SY_TIMEOUT__A, &data);
7590 WR16(demod->myI2CDevAddr,
7591 QAM_SY_TIMEOUT__A, data | 0x1);
7592 /* no need to wait lock */
7593 startTime =
7594 DRXBSP_HST_Clock() -
7595 DRXJ_QAM_MAX_WAITTIME - timeoutOfs;
7596 }
7597 }
7598 break;
7599 default:
7600 break;
7601 }
7602 DRXBSP_HST_Sleep(10);
7603 } while
7604 ((*lockStatus != DRX_LOCKED) &&
7605 (*lockStatus != DRX_NEVER_LOCK) &&
7606 ((DRXBSP_HST_Clock() - startTime) <
7607 (DRXJ_QAM_MAX_WAITTIME + timeoutOfs))
7608 );
7609 /* Returning control to apllication ... */
7610
7611 return (DRX_STS_OK);
7612 rw_error:
7613 return (DRX_STS_ERROR);
7614 }
7615
7616 /**
7617 * \fn DRXStatus_t QAM256Auto ()
7618 * \brief auto do sync pattern switching and mirroring.
7619 * \param demod: instance of demod.
7620 * \param channel: pointer to channel data.
7621 * \param tunerFreqOffset: tuner frequency offset.
7622 * \param lockStatus: pointer to lock status.
7623 * \return DRXStatus_t.
7624 */
7625 static DRXStatus_t
7626 QAM256Auto(pDRXDemodInstance_t demod,
7627 pDRXChannel_t channel,
7628 DRXFrequency_t tunerFreqOffset, pDRXLockStatus_t lockStatus)
7629 {
7630 DRXSigQuality_t sigQuality;
7631 u32_t state = NO_LOCK;
7632 u32_t startTime = 0;
7633 u32_t dLockedTime = 0;
7634 pDRXJData_t extAttr = NULL;
7635 u32_t timeoutOfs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
7636
7637 /* external attributes for storing aquired channel constellation */
7638 extAttr = (pDRXJData_t) demod->myExtAttr;
7639 *lockStatus = DRX_NOT_LOCKED;
7640 startTime = DRXBSP_HST_Clock();
7641 state = NO_LOCK;
7642 do {
7643 CHK_ERROR(CtrlLockStatus(demod, lockStatus));
7644 switch (state) {
7645 case NO_LOCK:
7646 if (*lockStatus == DRXJ_DEMOD_LOCK) {
7647 CHK_ERROR(CtrlGetQAMSigQuality
7648 (demod, &sigQuality));
7649 if (sigQuality.MER > 268) {
7650 state = DEMOD_LOCKED;
7651 timeoutOfs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
7652 dLockedTime = DRXBSP_HST_Clock();
7653 }
7654 }
7655 break;
7656 case DEMOD_LOCKED:
7657 if (*lockStatus == DRXJ_DEMOD_LOCK) {
7658 if ((channel->mirror == DRX_MIRROR_AUTO) &&
7659 ((DRXBSP_HST_Clock() - dLockedTime) >
7660 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
7661 extAttr->mirror = DRX_MIRROR_YES;
7662 CHK_ERROR(qamFlipSpec(demod, channel));
7663 state = SPEC_MIRRORED;
7664 /* reset timer TODO: still need 300ms? */
7665 startTime = DRXBSP_HST_Clock();
7666 timeoutOfs = -DRXJ_QAM_MAX_WAITTIME / 2;
7667 }
7668 }
7669 break;
7670 case SPEC_MIRRORED:
7671 break;
7672 default:
7673 break;
7674 }
7675 DRXBSP_HST_Sleep(10);
7676 } while
7677 ((*lockStatus < DRX_LOCKED) &&
7678 (*lockStatus != DRX_NEVER_LOCK) &&
7679 ((DRXBSP_HST_Clock() - startTime) <
7680 (DRXJ_QAM_MAX_WAITTIME + timeoutOfs)));
7681
7682 return (DRX_STS_OK);
7683 rw_error:
7684 return (DRX_STS_ERROR);
7685 }
7686
7687 /**
7688 * \fn DRXStatus_t SetQAMChannel ()
7689 * \brief Set QAM channel according to the requested constellation.
7690 * \param demod: instance of demod.
7691 * \param channel: pointer to channel data.
7692 * \return DRXStatus_t.
7693 */
7694 static DRXStatus_t
7695 SetQAMChannel(pDRXDemodInstance_t demod,
7696 pDRXChannel_t channel, DRXFrequency_t tunerFreqOffset)
7697 {
7698 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
7699 pDRXJData_t extAttr = NULL;
7700 Bool_t autoFlag = FALSE;
7701
7702 /* external attributes for storing aquired channel constellation */
7703 extAttr = (pDRXJData_t) demod->myExtAttr;
7704
7705 /* set QAM channel constellation */
7706 switch (channel->constellation) {
7707 case DRX_CONSTELLATION_QAM16:
7708 case DRX_CONSTELLATION_QAM32:
7709 case DRX_CONSTELLATION_QAM64:
7710 case DRX_CONSTELLATION_QAM128:
7711 case DRX_CONSTELLATION_QAM256:
7712 extAttr->constellation = channel->constellation;
7713 if (channel->mirror == DRX_MIRROR_AUTO) {
7714 extAttr->mirror = DRX_MIRROR_NO;
7715 } else {
7716 extAttr->mirror = channel->mirror;
7717 }
7718 CHK_ERROR(SetQAM
7719 (demod, channel, tunerFreqOffset, QAM_SET_OP_ALL));
7720
7721 if ((extAttr->standard == DRX_STANDARD_ITU_B) &&
7722 (channel->constellation == DRX_CONSTELLATION_QAM64)) {
7723 CHK_ERROR(QAM64Auto
7724 (demod, channel, tunerFreqOffset,
7725 &lockStatus));
7726 }
7727
7728 if ((extAttr->standard == DRX_STANDARD_ITU_B) &&
7729 (channel->mirror == DRX_MIRROR_AUTO) &&
7730 (channel->constellation == DRX_CONSTELLATION_QAM256)) {
7731 CHK_ERROR(QAM256Auto
7732 (demod, channel, tunerFreqOffset,
7733 &lockStatus));
7734 }
7735 break;
7736 case DRX_CONSTELLATION_AUTO: /* for channel scan */
7737 if (extAttr->standard == DRX_STANDARD_ITU_B) {
7738 autoFlag = TRUE;
7739 /* try to lock default QAM constellation: QAM64 */
7740 channel->constellation = DRX_CONSTELLATION_QAM256;
7741 extAttr->constellation = DRX_CONSTELLATION_QAM256;
7742 if (channel->mirror == DRX_MIRROR_AUTO) {
7743 extAttr->mirror = DRX_MIRROR_NO;
7744 } else {
7745 extAttr->mirror = channel->mirror;
7746 }
7747 CHK_ERROR(SetQAM
7748 (demod, channel, tunerFreqOffset,
7749 QAM_SET_OP_ALL));
7750 CHK_ERROR(QAM256Auto
7751 (demod, channel, tunerFreqOffset,
7752 &lockStatus));
7753
7754 if (lockStatus < DRX_LOCKED) {
7755 /* QAM254 not locked -> try to lock QAM64 constellation */
7756 channel->constellation =
7757 DRX_CONSTELLATION_QAM64;
7758 extAttr->constellation =
7759 DRX_CONSTELLATION_QAM64;
7760 if (channel->mirror == DRX_MIRROR_AUTO) {
7761 extAttr->mirror = DRX_MIRROR_NO;
7762 } else {
7763 extAttr->mirror = channel->mirror;
7764 }
7765 {
7766 u16_t qamCtlEna = 0;
7767 RR16(demod->myI2CDevAddr,
7768 SCU_RAM_QAM_CTL_ENA__A,
7769 &qamCtlEna);
7770 WR16(demod->myI2CDevAddr,
7771 SCU_RAM_QAM_CTL_ENA__A,
7772 qamCtlEna &
7773 ~SCU_RAM_QAM_CTL_ENA_ACQ__M);
7774 WR16(demod->myI2CDevAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2); /* force to rate hunting */
7775
7776 CHK_ERROR(SetQAM
7777 (demod, channel,
7778 tunerFreqOffset,
7779 QAM_SET_OP_CONSTELLATION));
7780 WR16(demod->myI2CDevAddr,
7781 SCU_RAM_QAM_CTL_ENA__A, qamCtlEna);
7782 }
7783 CHK_ERROR(QAM64Auto
7784 (demod, channel, tunerFreqOffset,
7785 &lockStatus));
7786 }
7787 channel->constellation = DRX_CONSTELLATION_AUTO;
7788 } else if (extAttr->standard == DRX_STANDARD_ITU_C) {
7789 channel->constellation = DRX_CONSTELLATION_QAM64;
7790 extAttr->constellation = DRX_CONSTELLATION_QAM64;
7791 autoFlag = TRUE;
7792
7793 if (channel->mirror == DRX_MIRROR_AUTO) {
7794 extAttr->mirror = DRX_MIRROR_NO;
7795 } else {
7796 extAttr->mirror = channel->mirror;
7797 }
7798 {
7799 u16_t qamCtlEna = 0;
7800 RR16(demod->myI2CDevAddr,
7801 SCU_RAM_QAM_CTL_ENA__A, &qamCtlEna);
7802 WR16(demod->myI2CDevAddr,
7803 SCU_RAM_QAM_CTL_ENA__A,
7804 qamCtlEna & ~SCU_RAM_QAM_CTL_ENA_ACQ__M);
7805 WR16(demod->myI2CDevAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2); /* force to rate hunting */
7806
7807 CHK_ERROR(SetQAM
7808 (demod, channel, tunerFreqOffset,
7809 QAM_SET_OP_CONSTELLATION));
7810 WR16(demod->myI2CDevAddr,
7811 SCU_RAM_QAM_CTL_ENA__A, qamCtlEna);
7812 }
7813 CHK_ERROR(QAM64Auto
7814 (demod, channel, tunerFreqOffset,
7815 &lockStatus));
7816 channel->constellation = DRX_CONSTELLATION_AUTO;
7817 } else {
7818 channel->constellation = DRX_CONSTELLATION_AUTO;
7819 return (DRX_STS_INVALID_ARG);
7820 }
7821 break;
7822 default:
7823 return (DRX_STS_INVALID_ARG);
7824 }
7825
7826 return (DRX_STS_OK);
7827 rw_error:
7828 /* restore starting value */
7829 if (autoFlag)
7830 channel->constellation = DRX_CONSTELLATION_AUTO;
7831 return (DRX_STS_ERROR);
7832 }
7833
7834 /*============================================================================*/
7835
7836 /**
7837 * \fn static short GetQAMRSErrCount(pI2CDeviceAddr_t devAddr)
7838 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
7839 * \return Error code
7840 *
7841 * precondition: measurement period & measurement prescale must be set
7842 *
7843 */
7844 static DRXStatus_t
7845 GetQAMRSErrCount(pI2CDeviceAddr_t devAddr, pDRXJRSErrors_t RSErrors)
7846 {
7847 u16_t nrBitErrors = 0,
7848 nrSymbolErrors = 0,
7849 nrPacketErrors = 0, nrFailures = 0, nrSncParFailCount = 0;
7850
7851 /* check arguments */
7852 if (devAddr == NULL) {
7853 return (DRX_STS_INVALID_ARG);
7854 }
7855
7856 /* all reported errors are received in the */
7857 /* most recently finished measurment period */
7858 /* no of pre RS bit errors */
7859 RR16(devAddr, FEC_RS_NR_BIT_ERRORS__A, &nrBitErrors);
7860 /* no of symbol errors */
7861 RR16(devAddr, FEC_RS_NR_SYMBOL_ERRORS__A, &nrSymbolErrors);
7862 /* no of packet errors */
7863 RR16(devAddr, FEC_RS_NR_PACKET_ERRORS__A, &nrPacketErrors);
7864 /* no of failures to decode */
7865 RR16(devAddr, FEC_RS_NR_FAILURES__A, &nrFailures);
7866 /* no of post RS bit erros */
7867 RR16(devAddr, FEC_OC_SNC_FAIL_COUNT__A, &nrSncParFailCount);
7868 /* TODO: NOTE */
7869 /* These register values are fetched in non-atomic fashion */
7870 /* It is possible that the read values contain unrelated information */
7871
7872 RSErrors->nrBitErrors = nrBitErrors & FEC_RS_NR_BIT_ERRORS__M;
7873 RSErrors->nrSymbolErrors = nrSymbolErrors & FEC_RS_NR_SYMBOL_ERRORS__M;
7874 RSErrors->nrPacketErrors = nrPacketErrors & FEC_RS_NR_PACKET_ERRORS__M;
7875 RSErrors->nrFailures = nrFailures & FEC_RS_NR_FAILURES__M;
7876 RSErrors->nrSncParFailCount =
7877 nrSncParFailCount & FEC_OC_SNC_FAIL_COUNT__M;
7878
7879 return (DRX_STS_OK);
7880 rw_error:
7881 return (DRX_STS_ERROR);
7882 }
7883
7884 /*============================================================================*/
7885
7886 /**
7887 * \fn DRXStatus_t CtrlGetQAMSigQuality()
7888 * \brief Retreive QAM signal quality from device.
7889 * \param devmod Pointer to demodulator instance.
7890 * \param sigQuality Pointer to signal quality data.
7891 * \return DRXStatus_t.
7892 * \retval DRX_STS_OK sigQuality contains valid data.
7893 * \retval DRX_STS_INVALID_ARG sigQuality is NULL.
7894 * \retval DRX_STS_ERROR Erroneous data, sigQuality contains invalid data.
7895
7896 * Pre-condition: Device must be started and in lock.
7897 */
7898 static DRXStatus_t
7899 CtrlGetQAMSigQuality(pDRXDemodInstance_t demod, pDRXSigQuality_t sigQuality)
7900 {
7901 pI2CDeviceAddr_t devAddr = NULL;
7902 pDRXJData_t extAttr = NULL;
7903 DRXConstellation_t constellation = DRX_CONSTELLATION_UNKNOWN;
7904 DRXJRSErrors_t measuredRSErrors = { 0, 0, 0, 0, 0 };
7905
7906 u32_t preBitErrRS = 0; /* pre RedSolomon Bit Error Rate */
7907 u32_t postBitErrRS = 0; /* post RedSolomon Bit Error Rate */
7908 u32_t pktErrs = 0; /* no of packet errors in RS */
7909 u16_t qamSlErrPower = 0; /* accumulated error between raw and sliced symbols */
7910 u16_t qsymErrVD = 0; /* quadrature symbol errors in QAM_VD */
7911 u16_t fecOcPeriod = 0; /* SNC sync failure measurement period */
7912 u16_t fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
7913 u16_t fecRsPeriod = 0; /* Value for corresponding I2C register */
7914 /* calculation constants */
7915 u32_t rsBitCnt = 0; /* RedSolomon Bit Count */
7916 u32_t qamSlSigPower = 0; /* used for MER, depends of QAM constellation */
7917 /* intermediate results */
7918 u32_t e = 0; /* exponent value used for QAM BER/SER */
7919 u32_t m = 0; /* mantisa value used for QAM BER/SER */
7920 u32_t berCnt = 0; /* BER count */
7921 /* signal quality info */
7922 u32_t qamSlMer = 0; /* QAM MER */
7923 u32_t qamPreRSBer = 0; /* Pre RedSolomon BER */
7924 u32_t qamPostRSBer = 0; /* Post RedSolomon BER */
7925 u32_t qamVDSer = 0; /* ViterbiDecoder SER */
7926 u16_t qamVdPrescale = 0; /* Viterbi Measurement Prescale */
7927 u16_t qamVdPeriod = 0; /* Viterbi Measurement period */
7928 u32_t vdBitCnt = 0; /* ViterbiDecoder Bit Count */
7929
7930 /* get device basic information */
7931 devAddr = demod->myI2CDevAddr;
7932 extAttr = (pDRXJData_t) demod->myExtAttr;
7933 constellation = extAttr->constellation;
7934
7935 /* read the physical registers */
7936 /* Get the RS error data */
7937 CHK_ERROR(GetQAMRSErrCount(devAddr, &measuredRSErrors));
7938 /* get the register value needed for MER */
7939 RR16(devAddr, QAM_SL_ERR_POWER__A, &qamSlErrPower);
7940 /* get the register value needed for post RS BER */
7941 RR16(devAddr, FEC_OC_SNC_FAIL_PERIOD__A, &fecOcPeriod);
7942
7943 /* get constants needed for signal quality calculation */
7944 fecRsPeriod = extAttr->fecRsPeriod;
7945 fecRsPrescale = extAttr->fecRsPrescale;
7946 rsBitCnt = fecRsPeriod * fecRsPrescale * extAttr->fecRsPlen;
7947 qamVdPeriod = extAttr->qamVdPeriod;
7948 qamVdPrescale = extAttr->qamVdPrescale;
7949 vdBitCnt = qamVdPeriod * qamVdPrescale * extAttr->fecVdPlen;
7950
7951 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
7952 switch (constellation) {
7953 case DRX_CONSTELLATION_QAM16:
7954 qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
7955 break;
7956 case DRX_CONSTELLATION_QAM32:
7957 qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
7958 break;
7959 case DRX_CONSTELLATION_QAM64:
7960 qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
7961 break;
7962 case DRX_CONSTELLATION_QAM128:
7963 qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
7964 break;
7965 case DRX_CONSTELLATION_QAM256:
7966 qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
7967 break;
7968 default:
7969 return (DRX_STS_ERROR);
7970 }
7971
7972 /* ------------------------------ */
7973 /* MER Calculation */
7974 /* ------------------------------ */
7975 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
7976
7977 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
7978 if (qamSlErrPower == 0)
7979 qamSlMer = 0;
7980 else
7981 qamSlMer =
7982 Log10Times100(qamSlSigPower) -
7983 Log10Times100((u32_t) qamSlErrPower);
7984
7985 /* ----------------------------------------- */
7986 /* Pre Viterbi Symbol Error Rate Calculation */
7987 /* ----------------------------------------- */
7988 /* pre viterbi SER is good if it is bellow 0.025 */
7989
7990 /* get the register value */
7991 /* no of quadrature symbol errors */
7992 RR16(devAddr, QAM_VD_NR_QSYM_ERRORS__A, &qsymErrVD);
7993 /* Extract the Exponent and the Mantisa */
7994 /* of number of quadrature symbol errors */
7995 e = (qsymErrVD & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
7996 QAM_VD_NR_QSYM_ERRORS_EXP__B;
7997 m = (qsymErrVD & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
7998 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
7999
8000 if ((m << e) >> 3 > 549752) { /* the max of FracTimes1e6 */
8001 qamVDSer = 500000; /* clip BER 0.5 */
8002 } else {
8003 qamVDSer =
8004 FracTimes1e6(m << ((e > 2) ? (e - 3) : e),
8005 vdBitCnt * ((e > 2) ? 1 : 8) / 8);
8006 }
8007
8008 /* --------------------------------------- */
8009 /* pre and post RedSolomon BER Calculation */
8010 /* --------------------------------------- */
8011 /* pre RS BER is good if it is below 3.5e-4 */
8012
8013 /* get the register values */
8014 preBitErrRS = (u32_t) measuredRSErrors.nrBitErrors;
8015 pktErrs = postBitErrRS = (u32_t) measuredRSErrors.nrSncParFailCount;
8016
8017 /* Extract the Exponent and the Mantisa of the */
8018 /* pre Reed-Solomon bit error count */
8019 e = (preBitErrRS & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
8020 FEC_RS_NR_BIT_ERRORS_EXP__B;
8021 m = (preBitErrRS & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
8022 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
8023
8024 berCnt = m << e;
8025
8026 /*qamPreRSBer = FracTimes1e6( berCnt, rsBitCnt ); */
8027 if (m > (rsBitCnt >> (e + 1)) || (rsBitCnt >> e) == 0) {
8028 qamPreRSBer = 500000; /* clip BER 0.5 */
8029 } else {
8030 qamPreRSBer = FracTimes1e6(m, rsBitCnt >> e);
8031 }
8032
8033 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
8034 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
8035 /*
8036 => c = (1000000*100*11.17)/1504 =
8037 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
8038 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
8039 *100 and /100 is for more precision.
8040 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
8041
8042 Precision errors still possible.
8043 */
8044 e = postBitErrRS * 742686;
8045 m = fecOcPeriod * 100;
8046 if (fecOcPeriod == 0)
8047 qamPostRSBer = 0xFFFFFFFF;
8048 else
8049 qamPostRSBer = e / m;
8050
8051 /* fill signal quality data structure */
8052 sigQuality->MER = ((u16_t) qamSlMer);
8053 if (extAttr->standard == DRX_STANDARD_ITU_B) {
8054 sigQuality->preViterbiBER = qamVDSer;
8055 } else {
8056 sigQuality->preViterbiBER = qamPreRSBer;
8057 }
8058 sigQuality->postViterbiBER = qamPreRSBer;
8059 sigQuality->postReedSolomonBER = qamPostRSBer;
8060 sigQuality->scaleFactorBER = ((u32_t) 1000000);
8061 #ifdef DRXJ_SIGNAL_ACCUM_ERR
8062 CHK_ERROR(GetAccPktErr(demod, &sigQuality->packetError));
8063 #else
8064 sigQuality->packetError = ((u16_t) pktErrs);
8065 #endif
8066
8067 return (DRX_STS_OK);
8068 rw_error:
8069 return (DRX_STS_ERROR);
8070 }
8071
8072 /**
8073 * \fn DRXStatus_t CtrlGetQAMConstel()
8074 * \brief Retreive a QAM constellation point via I2C.
8075 * \param demod Pointer to demodulator instance.
8076 * \param complexNr Pointer to the structure in which to store the
8077 constellation point.
8078 * \return DRXStatus_t.
8079 */
8080 static DRXStatus_t
8081 CtrlGetQAMConstel(pDRXDemodInstance_t demod, pDRXComplex_t complexNr)
8082 {
8083 u16_t fecOcOcrMode = 0;
8084 /**< FEC OCR grabber configuration */
8085 u16_t qamSlCommMb = 0;/**< QAM SL MB configuration */
8086 u16_t qamSlCommMbInit = 0;
8087 /**< QAM SL MB intial configuration */
8088 u16_t im = 0; /**< constellation Im part */
8089 u16_t re = 0; /**< constellation Re part */
8090 u32_t data = 0;
8091 pI2CDeviceAddr_t devAddr = NULL;
8092 /**< device address */
8093
8094 /* read device info */
8095 devAddr = demod->myI2CDevAddr;
8096
8097 /* TODO: */
8098 /* Monitor bus grabbing is an open external interface issue */
8099 /* Needs to be checked when external interface PG is updated */
8100
8101 /* Configure MB (Monitor bus) */
8102 RR16(devAddr, QAM_SL_COMM_MB__A, &qamSlCommMbInit);
8103 /* set observe flag & MB mux */
8104 qamSlCommMb = qamSlCommMbInit & (~(QAM_SL_COMM_MB_OBS__M +
8105 QAM_SL_COMM_MB_MUX_OBS__M));
8106 qamSlCommMb |= (QAM_SL_COMM_MB_OBS_ON +
8107 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
8108 WR16(devAddr, QAM_SL_COMM_MB__A, qamSlCommMb);
8109
8110 /* Enable MB grabber in the FEC OC */
8111 fecOcOcrMode = ( /* output select: observe bus */
8112 (FEC_OC_OCR_MODE_MB_SELECT__M &
8113 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
8114 /* grabber enable: on */
8115 (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
8116 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
8117 /* grabber select: observe bus */
8118 (FEC_OC_OCR_MODE_GRAB_SELECT__M &
8119 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
8120 /* grabber mode: continuous */
8121 (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
8122 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
8123 WR16(devAddr, FEC_OC_OCR_MODE__A, fecOcOcrMode);
8124
8125 /* Disable MB grabber in the FEC OC */
8126 WR16(devAddr, FEC_OC_OCR_MODE__A, 0x00);
8127
8128 /* read data */
8129 RR32(devAddr, FEC_OC_OCR_GRAB_RD0__A, &data);
8130 re = (u16_t) (data & FEC_OC_OCR_GRAB_RD0__M);
8131 im = (u16_t) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
8132
8133 /* TODO: */
8134 /* interpret data (re & im) according to the Monitor bus mapping ?? */
8135
8136 /* sign extension, 10th bit is sign bit */
8137 if ((re & 0x0200) == 0x0200) {
8138 re |= 0xFC00;
8139 }
8140 if ((im & 0x0200) == 0x0200) {
8141 im |= 0xFC00;
8142 }
8143 complexNr->re = ((s16_t) re);
8144 complexNr->im = ((s16_t) im);
8145
8146 /* Restore MB (Monitor bus) */
8147 WR16(devAddr, QAM_SL_COMM_MB__A, qamSlCommMbInit);
8148
8149 return (DRX_STS_OK);
8150 rw_error:
8151 return (DRX_STS_ERROR);
8152 }
8153 #endif /* #ifndef DRXJ_VSB_ONLY */
8154
8155 /*============================================================================*/
8156 /*== END QAM DATAPATH FUNCTIONS ==*/
8157 /*============================================================================*/
8158
8159 /*============================================================================*/
8160 /*============================================================================*/
8161 /*== ATV DATAPATH FUNCTIONS ==*/
8162 /*============================================================================*/
8163 /*============================================================================*/
8164
8165 /*
8166 Implementation notes.
8167
8168 NTSC/FM AGCs
8169
8170 Four AGCs are used for NTSC:
8171 (1) RF (used to attenuate the input signal in case of to much power)
8172 (2) IF (used to attenuate the input signal in case of to much power)
8173 (3) Video AGC (used to amplify the output signal in case input to low)
8174 (4) SIF AGC (used to amplify the output signal in case input to low)
8175
8176 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
8177 that the coupling between Video AGC and the RF and IF AGCs also works in
8178 favor of the SIF AGC.
8179
8180 Three AGCs are used for FM:
8181 (1) RF (used to attenuate the input signal in case of to much power)
8182 (2) IF (used to attenuate the input signal in case of to much power)
8183 (3) SIF AGC (used to amplify the output signal in case input to low)
8184
8185 The SIF AGC is now coupled to the RF/IF AGCs.
8186 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
8187 the AUD block.
8188
8189 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
8190 the ATV block. The AGC control algorithms are all implemented in
8191 microcode.
8192
8193 ATV SETTINGS
8194
8195 (Shadow settings will not be used for now, they will be implemented
8196 later on because of the schedule)
8197
8198 Several HW/SCU "settings" can be used for ATV. The standard selection
8199 will reset most of these settings. To avoid that the end user apllication
8200 has to perform these settings each time the ATV or FM standards is
8201 selected the driver will shadow these settings. This enables the end user
8202 to perform the settings only once after a DRX_Open(). The driver must
8203 write the shadow settings to HW/SCU incase:
8204 ( setstandard FM/ATV) ||
8205 ( settings have changed && FM/ATV standard is active)
8206 The shadow settings will be stored in the device specific data container.
8207 A set of flags will be defined to flag changes in shadow settings.
8208 A routine will be implemented to write all changed shadow settings to
8209 HW/SCU.
8210
8211 The "settings" will consist of: AGC settings, filter settings etc.
8212
8213 Disadvantage of use of shadow settings:
8214 Direct changes in HW/SCU registers will not be reflected in the
8215 shadow settings and these changes will be overwritten during a next
8216 update. This can happen during evaluation. This will not be a problem
8217 for normal customer usage.
8218 */
8219 /* -------------------------------------------------------------------------- */
8220
8221 /**
8222 * \brief Get array index for atv coef (extAttr->atvTopCoefX[index])
8223 * \param standard
8224 * \param pointer to index
8225 * \return DRXStatus_t.
8226 *
8227 */
8228 static DRXStatus_t AtvEquCoefIndex(DRXStandard_t standard, int *index)
8229 {
8230 switch (standard) {
8231 case DRX_STANDARD_PAL_SECAM_BG:
8232 *index = (int)DRXJ_COEF_IDX_BG;
8233 break;
8234 case DRX_STANDARD_PAL_SECAM_DK:
8235 *index = (int)DRXJ_COEF_IDX_DK;
8236 break;
8237 case DRX_STANDARD_PAL_SECAM_I:
8238 *index = (int)DRXJ_COEF_IDX_I;
8239 break;
8240 case DRX_STANDARD_PAL_SECAM_L:
8241 *index = (int)DRXJ_COEF_IDX_L;
8242 break;
8243 case DRX_STANDARD_PAL_SECAM_LP:
8244 *index = (int)DRXJ_COEF_IDX_LP;
8245 break;
8246 case DRX_STANDARD_NTSC:
8247 *index = (int)DRXJ_COEF_IDX_MN;
8248 break;
8249 case DRX_STANDARD_FM:
8250 *index = (int)DRXJ_COEF_IDX_FM;
8251 break;
8252 default:
8253 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
8254 return DRX_STS_ERROR;
8255 break;
8256 }
8257
8258 return DRX_STS_OK;
8259 }
8260
8261 /* -------------------------------------------------------------------------- */
8262 /**
8263 * \fn DRXStatus_t AtvUpdateConfig ()
8264 * \brief Flush changes in ATV shadow registers to physical registers.
8265 * \param demod instance of demodulator
8266 * \param forceUpdate don't look at standard or change flags, flush all.
8267 * \return DRXStatus_t.
8268 *
8269 */
8270 static DRXStatus_t
8271 AtvUpdateConfig(pDRXDemodInstance_t demod, Bool_t forceUpdate)
8272 {
8273 pI2CDeviceAddr_t devAddr = NULL;
8274 pDRXJData_t extAttr = NULL;
8275
8276 devAddr = demod->myI2CDevAddr;
8277 extAttr = (pDRXJData_t) demod->myExtAttr;
8278
8279 /* equalizer coefficients */
8280 if (forceUpdate ||
8281 ((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_COEF) != 0)) {
8282 int index = 0;
8283
8284 CHK_ERROR(AtvEquCoefIndex(extAttr->standard, &index));
8285 WR16(devAddr, ATV_TOP_EQU0__A, extAttr->atvTopEqu0[index]);
8286 WR16(devAddr, ATV_TOP_EQU1__A, extAttr->atvTopEqu1[index]);
8287 WR16(devAddr, ATV_TOP_EQU2__A, extAttr->atvTopEqu2[index]);
8288 WR16(devAddr, ATV_TOP_EQU3__A, extAttr->atvTopEqu3[index]);
8289 }
8290
8291 /* bypass fast carrier recovery */
8292 if (forceUpdate) {
8293 u16_t data = 0;
8294
8295 RR16(devAddr, IQM_RT_ROT_BP__A, &data);
8296 data &= (~((u16_t) IQM_RT_ROT_BP_ROT_OFF__M));
8297 if (extAttr->phaseCorrectionBypass) {
8298 data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
8299 } else {
8300 data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
8301 }
8302 WR16(devAddr, IQM_RT_ROT_BP__A, data);
8303 }
8304
8305 /* peak filter setting */
8306 if (forceUpdate ||
8307 ((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
8308 WR16(devAddr, ATV_TOP_VID_PEAK__A, extAttr->atvTopVidPeak);
8309 }
8310
8311 /* noise filter setting */
8312 if (forceUpdate ||
8313 ((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
8314 WR16(devAddr, ATV_TOP_NOISE_TH__A, extAttr->atvTopNoiseTh);
8315 }
8316
8317 /* SIF attenuation */
8318 if (forceUpdate ||
8319 ((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
8320 u16_t attenuation = 0;
8321
8322 switch (extAttr->sifAttenuation) {
8323 case DRXJ_SIF_ATTENUATION_0DB:
8324 attenuation = ATV_TOP_AF_SIF_ATT_0DB;
8325 break;
8326 case DRXJ_SIF_ATTENUATION_3DB:
8327 attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
8328 break;
8329 case DRXJ_SIF_ATTENUATION_6DB:
8330 attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
8331 break;
8332 case DRXJ_SIF_ATTENUATION_9DB:
8333 attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
8334 break;
8335 default:
8336 return DRX_STS_ERROR;
8337 break;
8338 }
8339 WR16(devAddr, ATV_TOP_AF_SIF_ATT__A, attenuation);
8340 }
8341
8342 /* SIF & CVBS enable */
8343 if (forceUpdate ||
8344 ((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
8345 u16_t data = 0;
8346
8347 RR16(devAddr, ATV_TOP_STDBY__A, &data);
8348 if (extAttr->enableCVBSOutput) {
8349 data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
8350 } else {
8351 data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
8352 }
8353
8354 if (extAttr->enableSIFOutput) {
8355 data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
8356 } else {
8357 data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
8358 }
8359 WR16(devAddr, ATV_TOP_STDBY__A, data);
8360 }
8361
8362 extAttr->atvCfgChangedFlags = 0;
8363
8364 return (DRX_STS_OK);
8365 rw_error:
8366 return (DRX_STS_ERROR);
8367 }
8368
8369 /* -------------------------------------------------------------------------- */
8370 /**
8371 * \fn DRXStatus_t CtrlSetCfgATVOutput()
8372 * \brief Configure ATV ouputs
8373 * \param demod instance of demodulator
8374 * \param outputCfg output configuaration
8375 * \return DRXStatus_t.
8376 *
8377 */
8378 static DRXStatus_t
8379 CtrlSetCfgATVOutput(pDRXDemodInstance_t demod, pDRXJCfgAtvOutput_t outputCfg)
8380 {
8381 pDRXJData_t extAttr = NULL;
8382
8383 /* Check arguments */
8384 if (outputCfg == NULL) {
8385 return (DRX_STS_INVALID_ARG);
8386 }
8387
8388 extAttr = (pDRXJData_t) demod->myExtAttr;
8389 if (outputCfg->enableSIFOutput) {
8390 switch (outputCfg->sifAttenuation) {
8391 case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
8392 case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
8393 case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
8394 case DRXJ_SIF_ATTENUATION_9DB:
8395 /* Do nothing */
8396 break;
8397 default:
8398 return DRX_STS_INVALID_ARG;
8399 break;
8400 }
8401
8402 if (extAttr->sifAttenuation != outputCfg->sifAttenuation) {
8403 extAttr->sifAttenuation = outputCfg->sifAttenuation;
8404 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_SIF_ATT;
8405 }
8406 }
8407
8408 if (extAttr->enableCVBSOutput != outputCfg->enableCVBSOutput) {
8409 extAttr->enableCVBSOutput = outputCfg->enableCVBSOutput;
8410 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_OUTPUT;
8411 }
8412
8413 if (extAttr->enableSIFOutput != outputCfg->enableSIFOutput) {
8414 extAttr->enableSIFOutput = outputCfg->enableSIFOutput;
8415 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_OUTPUT;
8416 }
8417
8418 CHK_ERROR(AtvUpdateConfig(demod, FALSE));
8419
8420 return (DRX_STS_OK);
8421 rw_error:
8422 return (DRX_STS_ERROR);
8423 }
8424
8425 /* -------------------------------------------------------------------------- */
8426 #ifndef DRXJ_DIGITAL_ONLY
8427 /**
8428 * \fn DRXStatus_t CtrlSetCfgAtvEquCoef()
8429 * \brief Set ATV equalizer coefficients
8430 * \param demod instance of demodulator
8431 * \param coef the equalizer coefficients
8432 * \return DRXStatus_t.
8433 *
8434 */
8435 static DRXStatus_t
8436 CtrlSetCfgAtvEquCoef(pDRXDemodInstance_t demod, pDRXJCfgAtvEquCoef_t coef)
8437 {
8438 pDRXJData_t extAttr = NULL;
8439 int index;
8440
8441 extAttr = (pDRXJData_t) demod->myExtAttr;
8442
8443 /* current standard needs to be an ATV standard */
8444 if (!DRXJ_ISATVSTD(extAttr->standard)) {
8445 return DRX_STS_ERROR;
8446 }
8447
8448 /* Check arguments */
8449 if ((coef == NULL) ||
8450 (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
8451 (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
8452 (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
8453 (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
8454 (coef->coef0 < ((s16_t) ~ (ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
8455 (coef->coef1 < ((s16_t) ~ (ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
8456 (coef->coef2 < ((s16_t) ~ (ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
8457 (coef->coef3 < ((s16_t) ~ (ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
8458 return (DRX_STS_INVALID_ARG);
8459 }
8460
8461 CHK_ERROR(AtvEquCoefIndex(extAttr->standard, &index));
8462 extAttr->atvTopEqu0[index] = coef->coef0;
8463 extAttr->atvTopEqu1[index] = coef->coef1;
8464 extAttr->atvTopEqu2[index] = coef->coef2;
8465 extAttr->atvTopEqu3[index] = coef->coef3;
8466 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_COEF;
8467
8468 CHK_ERROR(AtvUpdateConfig(demod, FALSE));
8469
8470 return (DRX_STS_OK);
8471 rw_error:
8472 return (DRX_STS_ERROR);
8473 }
8474
8475 /* -------------------------------------------------------------------------- */
8476 /**
8477 * \fn DRXStatus_t CtrlGetCfgAtvEquCoef()
8478 * \brief Get ATV equ coef settings
8479 * \param demod instance of demodulator
8480 * \param coef The ATV equ coefficients
8481 * \return DRXStatus_t.
8482 *
8483 * The values are read from the shadow registers maintained by the drxdriver
8484 * If registers are manipulated outside of the drxdriver scope the reported
8485 * settings will not reflect these changes because of the use of shadow
8486 * regitsers.
8487 *
8488 */
8489 static DRXStatus_t
8490 CtrlGetCfgAtvEquCoef(pDRXDemodInstance_t demod, pDRXJCfgAtvEquCoef_t coef)
8491 {
8492 pDRXJData_t extAttr = NULL;
8493 int index = 0;
8494
8495 extAttr = (pDRXJData_t) demod->myExtAttr;
8496
8497 /* current standard needs to be an ATV standard */
8498 if (!DRXJ_ISATVSTD(extAttr->standard)) {
8499 return DRX_STS_ERROR;
8500 }
8501
8502 /* Check arguments */
8503 if (coef == NULL) {
8504 return DRX_STS_INVALID_ARG;
8505 }
8506
8507 CHK_ERROR(AtvEquCoefIndex(extAttr->standard, &index));
8508 coef->coef0 = extAttr->atvTopEqu0[index];
8509 coef->coef1 = extAttr->atvTopEqu1[index];
8510 coef->coef2 = extAttr->atvTopEqu2[index];
8511 coef->coef3 = extAttr->atvTopEqu3[index];
8512
8513 return (DRX_STS_OK);
8514 rw_error:
8515 return (DRX_STS_ERROR);
8516 }
8517
8518 /* -------------------------------------------------------------------------- */
8519 /**
8520 * \fn DRXStatus_t CtrlSetCfgAtvMisc()
8521 * \brief Set misc. settings for ATV.
8522 * \param demod instance of demodulator
8523 * \param
8524 * \return DRXStatus_t.
8525 *
8526 */
8527 static DRXStatus_t
8528 CtrlSetCfgAtvMisc(pDRXDemodInstance_t demod, pDRXJCfgAtvMisc_t settings)
8529 {
8530 pDRXJData_t extAttr = NULL;
8531
8532 /* Check arguments */
8533 if ((settings == NULL) ||
8534 ((settings->peakFilter) < (s16_t) (-8)) ||
8535 ((settings->peakFilter) > (s16_t) (15)) ||
8536 ((settings->noiseFilter) > 15)) {
8537 return (DRX_STS_INVALID_ARG);
8538 }
8539 /* if */
8540 extAttr = (pDRXJData_t) demod->myExtAttr;
8541
8542 if (settings->peakFilter != extAttr->atvTopVidPeak) {
8543 extAttr->atvTopVidPeak = settings->peakFilter;
8544 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_PEAK_FLT;
8545 }
8546
8547 if (settings->noiseFilter != extAttr->atvTopNoiseTh) {
8548 extAttr->atvTopNoiseTh = settings->noiseFilter;
8549 extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_NOISE_FLT;
8550 }
8551
8552 CHK_ERROR(AtvUpdateConfig(demod, FALSE));
8553
8554 return (DRX_STS_OK);
8555 rw_error:
8556 return (DRX_STS_ERROR);
8557 }
8558
8559 /* -------------------------------------------------------------------------- */
8560 /**
8561 * \fn DRXStatus_t CtrlGetCfgAtvMisc()
8562 * \brief Get misc settings of ATV.
8563 * \param demod instance of demodulator
8564 * \param settings misc. ATV settings
8565 * \return DRXStatus_t.
8566 *
8567 * The values are read from the shadow registers maintained by the drxdriver
8568 * If registers are manipulated outside of the drxdriver scope the reported
8569 * settings will not reflect these changes because of the use of shadow
8570 * regitsers.
8571 */
8572 static DRXStatus_t
8573 CtrlGetCfgAtvMisc(pDRXDemodInstance_t demod, pDRXJCfgAtvMisc_t settings)
8574 {
8575 pDRXJData_t extAttr = NULL;
8576
8577 /* Check arguments */
8578 if (settings == NULL) {
8579 return DRX_STS_INVALID_ARG;
8580 }
8581
8582 extAttr = (pDRXJData_t) demod->myExtAttr;
8583
8584 settings->peakFilter = extAttr->atvTopVidPeak;
8585 settings->noiseFilter = extAttr->atvTopNoiseTh;
8586
8587 return (DRX_STS_OK);
8588 }
8589
8590 /* -------------------------------------------------------------------------- */
8591
8592 /* -------------------------------------------------------------------------- */
8593 /**
8594 * \fn DRXStatus_t CtrlGetCfgAtvOutput()
8595 * \brief
8596 * \param demod instance of demodulator
8597 * \param outputCfg output configuaration
8598 * \return DRXStatus_t.
8599 *
8600 */
8601 static DRXStatus_t
8602 CtrlGetCfgAtvOutput(pDRXDemodInstance_t demod, pDRXJCfgAtvOutput_t outputCfg)
8603 {
8604 u16_t data = 0;
8605
8606 /* Check arguments */
8607 if (outputCfg == NULL) {
8608 return DRX_STS_INVALID_ARG;
8609 }
8610
8611 RR16(demod->myI2CDevAddr, ATV_TOP_STDBY__A, &data);
8612 if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) {
8613 outputCfg->enableCVBSOutput = TRUE;
8614 } else {
8615 outputCfg->enableCVBSOutput = FALSE;
8616 }
8617
8618 if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
8619 outputCfg->enableSIFOutput = FALSE;
8620 } else {
8621 outputCfg->enableSIFOutput = TRUE;
8622 RR16(demod->myI2CDevAddr, ATV_TOP_AF_SIF_ATT__A, &data);
8623 outputCfg->sifAttenuation = (DRXJSIFAttenuation_t) data;
8624 }
8625
8626 return (DRX_STS_OK);
8627 rw_error:
8628 return (DRX_STS_ERROR);
8629 }
8630
8631 /* -------------------------------------------------------------------------- */
8632 /**
8633 * \fn DRXStatus_t CtrlGetCfgAtvAgcStatus()
8634 * \brief
8635 * \param demod instance of demodulator
8636 * \param agcStatus agc status
8637 * \return DRXStatus_t.
8638 *
8639 */
8640 static DRXStatus_t
8641 CtrlGetCfgAtvAgcStatus(pDRXDemodInstance_t demod,
8642 pDRXJCfgAtvAgcStatus_t agcStatus)
8643 {
8644 pI2CDeviceAddr_t devAddr = NULL;
8645 pDRXJData_t extAttr = NULL;
8646 u16_t data = 0;
8647 u32_t tmp = 0;
8648
8649 /* Check arguments */
8650 if (agcStatus == NULL) {
8651 return DRX_STS_INVALID_ARG;
8652 }
8653
8654 devAddr = demod->myI2CDevAddr;
8655 extAttr = (pDRXJData_t) demod->myExtAttr;
8656
8657 /*
8658 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
8659 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
8660
8661 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
8662 */
8663 RR16(devAddr, IQM_AF_AGC_RF__A, &data);
8664 tmp = ((u32_t) data) * 27 - ((u32_t) (data >> 2)); /* nA */
8665 agcStatus->rfAgcGain = (u16_t) (tmp / 1000); /* uA */
8666 /* rounding */
8667 if (tmp % 1000 >= 500) {
8668 (agcStatus->rfAgcGain)++;
8669 }
8670
8671 /*
8672 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
8673 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
8674
8675 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
8676 */
8677 RR16(devAddr, IQM_AF_AGC_IF__A, &data);
8678 tmp = ((u32_t) data) * 27 - ((u32_t) (data >> 2)); /* nA */
8679 agcStatus->ifAgcGain = (u16_t) (tmp / 1000); /* uA */
8680 /* rounding */
8681 if (tmp % 1000 >= 500) {
8682 (agcStatus->ifAgcGain)++;
8683 }
8684
8685 /*
8686 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
8687 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
8688 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
8689 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
8690 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
8691 */
8692
8693 SARR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, &data);
8694 /* dividing by 32 inclusive rounding */
8695 data >>= 4;
8696 if ((data & 1) != 0) {
8697 data++;
8698 }
8699 data >>= 1;
8700 agcStatus->videoAgcGain = ((s16_t) data) - 75; /* 0.1 dB */
8701
8702 /*
8703 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
8704 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
8705 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
8706 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
8707 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
8708 */
8709
8710 SARR16(devAddr, SCU_RAM_ATV_SIF_GAIN__A, &data);
8711 data &= SCU_RAM_ATV_SIF_GAIN__M;
8712 /* dividing by 2 inclusive rounding */
8713 if ((data & 1) != 0) {
8714 data++;
8715 }
8716 data >>= 1;
8717 agcStatus->audioAgcGain = ((s16_t) data) - 4; /* 0.1 dB */
8718
8719 /* Loop gain's */
8720 SARR16(devAddr, SCU_RAM_AGC_KI__A, &data);
8721 agcStatus->videoAgcLoopGain =
8722 ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
8723 agcStatus->rfAgcLoopGain =
8724 ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
8725 agcStatus->ifAgcLoopGain =
8726 ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
8727
8728 return (DRX_STS_OK);
8729 rw_error:
8730 return (DRX_STS_ERROR);
8731 }
8732
8733 /* -------------------------------------------------------------------------- */
8734
8735 /**
8736 * \fn DRXStatus_t PowerUpATV ()
8737 * \brief Power up ATV.
8738 * \param demod instance of demodulator
8739 * \param standard either NTSC or FM (sub strandard for ATV )
8740 * \return DRXStatus_t.
8741 *
8742 * * Starts ATV and IQM
8743 * * AUdio already started during standard init for ATV.
8744 */
8745 static DRXStatus_t PowerUpATV(pDRXDemodInstance_t demod, DRXStandard_t standard)
8746 {
8747 pI2CDeviceAddr_t devAddr = NULL;
8748 pDRXJData_t extAttr = NULL;
8749
8750 devAddr = demod->myI2CDevAddr;
8751 extAttr = (pDRXJData_t) demod->myExtAttr;
8752
8753 /* ATV NTSC */
8754 WR16(devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE);
8755 /* turn on IQM_AF */
8756 CHK_ERROR(SetIqmAf(demod, TRUE));
8757 CHK_ERROR(ADCSynchronization(demod));
8758
8759 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
8760
8761 /* Audio, already done during set standard */
8762
8763 return (DRX_STS_OK);
8764 rw_error:
8765 return (DRX_STS_ERROR);
8766 }
8767 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
8768
8769 /* -------------------------------------------------------------------------- */
8770
8771 /**
8772 * \fn DRXStatus_t PowerDownATV ()
8773 * \brief Power down ATV.
8774 * \param demod instance of demodulator
8775 * \param standard either NTSC or FM (sub strandard for ATV )
8776 * \return DRXStatus_t.
8777 *
8778 * Stops and thus resets ATV and IQM block
8779 * SIF and CVBS ADC are powered down
8780 * Calls audio power down
8781 */
8782 static DRXStatus_t
8783 PowerDownATV(pDRXDemodInstance_t demod, DRXStandard_t standard, Bool_t primary)
8784 {
8785 pI2CDeviceAddr_t devAddr = NULL;
8786 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
8787 /* parameterLen */ 0,
8788 /* resultLen */ 0,
8789 /* *parameter */ NULL,
8790 /* *result */ NULL
8791 };
8792 u16_t cmdResult = 0;
8793 pDRXJData_t extAttr = NULL;
8794
8795 devAddr = demod->myI2CDevAddr;
8796 extAttr = (pDRXJData_t) demod->myExtAttr;
8797 /* ATV NTSC */
8798
8799 /* Stop ATV SCU (will reset ATV and IQM hardware */
8800 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
8801 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
8802 cmdSCU.parameterLen = 0;
8803 cmdSCU.resultLen = 1;
8804 cmdSCU.parameter = NULL;
8805 cmdSCU.result = &cmdResult;
8806 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
8807 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
8808 WR16(devAddr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY &
8809 (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)));
8810
8811 WR16(devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP);
8812 if (primary == TRUE) {
8813 WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
8814 CHK_ERROR(SetIqmAf(demod, FALSE));
8815 } else {
8816 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
8817 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
8818 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
8819 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
8820 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
8821 }
8822 CHK_ERROR(PowerDownAud(demod));
8823
8824 return (DRX_STS_OK);
8825 rw_error:
8826 return (DRX_STS_ERROR);
8827 }
8828
8829 /* -------------------------------------------------------------------------- */
8830 /**
8831 * \fn DRXStatus_t SetATVStandard ()
8832 * \brief Set up ATV demodulator.
8833 * \param demod instance of demodulator
8834 * \param standard either NTSC or FM (sub strandard for ATV )
8835 * \return DRXStatus_t.
8836 *
8837 * Init all channel independent registers.
8838 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
8839 *
8840 */
8841 #ifndef DRXJ_DIGITAL_ONLY
8842 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
8843 static DRXStatus_t
8844 SetATVStandard(pDRXDemodInstance_t demod, pDRXStandard_t standard)
8845 {
8846 /* TODO: enable alternative for tap settings via external file
8847
8848 something like:
8849 #ifdef DRXJ_ATV_COEF_FILE
8850 #include DRXJ_ATV_COEF_FILE
8851 #else
8852 ... code defining fixed coef's ...
8853 #endif
8854
8855 Cutsomer must create file "customer_coefs.c.inc" containing
8856 modified copy off the constants below, and define the compiler
8857 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
8858
8859 Still to check if this will work; DRXJ_16TO8 macro may cause
8860 trouble ?
8861 */
8862 const u8_t ntsc_taps_re[] = {
8863 DRXJ_16TO8(-12), /* re0 */
8864 DRXJ_16TO8(-9), /* re1 */
8865 DRXJ_16TO8(9), /* re2 */
8866 DRXJ_16TO8(19), /* re3 */
8867 DRXJ_16TO8(-4), /* re4 */
8868 DRXJ_16TO8(-24), /* re5 */
8869 DRXJ_16TO8(-6), /* re6 */
8870 DRXJ_16TO8(16), /* re7 */
8871 DRXJ_16TO8(6), /* re8 */
8872 DRXJ_16TO8(-16), /* re9 */
8873 DRXJ_16TO8(-5), /* re10 */
8874 DRXJ_16TO8(13), /* re11 */
8875 DRXJ_16TO8(-2), /* re12 */
8876 DRXJ_16TO8(-20), /* re13 */
8877 DRXJ_16TO8(4), /* re14 */
8878 DRXJ_16TO8(25), /* re15 */
8879 DRXJ_16TO8(-6), /* re16 */
8880 DRXJ_16TO8(-36), /* re17 */
8881 DRXJ_16TO8(2), /* re18 */
8882 DRXJ_16TO8(38), /* re19 */
8883 DRXJ_16TO8(-10), /* re20 */
8884 DRXJ_16TO8(-48), /* re21 */
8885 DRXJ_16TO8(35), /* re22 */
8886 DRXJ_16TO8(94), /* re23 */
8887 DRXJ_16TO8(-59), /* re24 */
8888 DRXJ_16TO8(-217), /* re25 */
8889 DRXJ_16TO8(50), /* re26 */
8890 DRXJ_16TO8(679) /* re27 */
8891 };
8892 const u8_t ntsc_taps_im[] = {
8893 DRXJ_16TO8(11), /* im0 */
8894 DRXJ_16TO8(1), /* im1 */
8895 DRXJ_16TO8(-10), /* im2 */
8896 DRXJ_16TO8(2), /* im3 */
8897 DRXJ_16TO8(24), /* im4 */
8898 DRXJ_16TO8(21), /* im5 */
8899 DRXJ_16TO8(1), /* im6 */
8900 DRXJ_16TO8(-4), /* im7 */
8901 DRXJ_16TO8(7), /* im8 */
8902 DRXJ_16TO8(14), /* im9 */
8903 DRXJ_16TO8(27), /* im10 */
8904 DRXJ_16TO8(42), /* im11 */
8905 DRXJ_16TO8(22), /* im12 */
8906 DRXJ_16TO8(-20), /* im13 */
8907 DRXJ_16TO8(2), /* im14 */
8908 DRXJ_16TO8(98), /* im15 */
8909 DRXJ_16TO8(122), /* im16 */
8910 DRXJ_16TO8(0), /* im17 */
8911 DRXJ_16TO8(-85), /* im18 */
8912 DRXJ_16TO8(51), /* im19 */
8913 DRXJ_16TO8(247), /* im20 */
8914 DRXJ_16TO8(192), /* im21 */
8915 DRXJ_16TO8(-55), /* im22 */
8916 DRXJ_16TO8(-95), /* im23 */
8917 DRXJ_16TO8(217), /* im24 */
8918 DRXJ_16TO8(544), /* im25 */
8919 DRXJ_16TO8(553), /* im26 */
8920 DRXJ_16TO8(302) /* im27 */
8921 };
8922 const u8_t bg_taps_re[] = {
8923 DRXJ_16TO8(-18), /* re0 */
8924 DRXJ_16TO8(18), /* re1 */
8925 DRXJ_16TO8(19), /* re2 */
8926 DRXJ_16TO8(-26), /* re3 */
8927 DRXJ_16TO8(-20), /* re4 */
8928 DRXJ_16TO8(36), /* re5 */
8929 DRXJ_16TO8(5), /* re6 */
8930 DRXJ_16TO8(-51), /* re7 */
8931 DRXJ_16TO8(15), /* re8 */
8932 DRXJ_16TO8(45), /* re9 */
8933 DRXJ_16TO8(-46), /* re10 */
8934 DRXJ_16TO8(-24), /* re11 */
8935 DRXJ_16TO8(71), /* re12 */
8936 DRXJ_16TO8(-17), /* re13 */
8937 DRXJ_16TO8(-83), /* re14 */
8938 DRXJ_16TO8(74), /* re15 */
8939 DRXJ_16TO8(75), /* re16 */
8940 DRXJ_16TO8(-134), /* re17 */
8941 DRXJ_16TO8(-40), /* re18 */
8942 DRXJ_16TO8(191), /* re19 */
8943 DRXJ_16TO8(-11), /* re20 */
8944 DRXJ_16TO8(-233), /* re21 */
8945 DRXJ_16TO8(74), /* re22 */
8946 DRXJ_16TO8(271), /* re23 */
8947 DRXJ_16TO8(-132), /* re24 */
8948 DRXJ_16TO8(-341), /* re25 */
8949 DRXJ_16TO8(172), /* re26 */
8950 DRXJ_16TO8(801) /* re27 */
8951 };
8952 const u8_t bg_taps_im[] = {
8953 DRXJ_16TO8(-24), /* im0 */
8954 DRXJ_16TO8(-10), /* im1 */
8955 DRXJ_16TO8(9), /* im2 */
8956 DRXJ_16TO8(-5), /* im3 */
8957 DRXJ_16TO8(-51), /* im4 */
8958 DRXJ_16TO8(-17), /* im5 */
8959 DRXJ_16TO8(31), /* im6 */
8960 DRXJ_16TO8(-48), /* im7 */
8961 DRXJ_16TO8(-95), /* im8 */
8962 DRXJ_16TO8(25), /* im9 */
8963 DRXJ_16TO8(37), /* im10 */
8964 DRXJ_16TO8(-123), /* im11 */
8965 DRXJ_16TO8(-77), /* im12 */
8966 DRXJ_16TO8(94), /* im13 */
8967 DRXJ_16TO8(-10), /* im14 */
8968 DRXJ_16TO8(-149), /* im15 */
8969 DRXJ_16TO8(10), /* im16 */
8970 DRXJ_16TO8(108), /* im17 */
8971 DRXJ_16TO8(-49), /* im18 */
8972 DRXJ_16TO8(-59), /* im19 */
8973 DRXJ_16TO8(90), /* im20 */
8974 DRXJ_16TO8(73), /* im21 */
8975 DRXJ_16TO8(55), /* im22 */
8976 DRXJ_16TO8(148), /* im23 */
8977 DRXJ_16TO8(86), /* im24 */
8978 DRXJ_16TO8(146), /* im25 */
8979 DRXJ_16TO8(687), /* im26 */
8980 DRXJ_16TO8(877) /* im27 */
8981 };
8982 const u8_t dk_i_l_lp_taps_re[] = {
8983 DRXJ_16TO8(-23), /* re0 */
8984 DRXJ_16TO8(9), /* re1 */
8985 DRXJ_16TO8(16), /* re2 */
8986 DRXJ_16TO8(-26), /* re3 */
8987 DRXJ_16TO8(-3), /* re4 */
8988 DRXJ_16TO8(13), /* re5 */
8989 DRXJ_16TO8(-19), /* re6 */
8990 DRXJ_16TO8(-3), /* re7 */
8991 DRXJ_16TO8(13), /* re8 */
8992 DRXJ_16TO8(-26), /* re9 */
8993 DRXJ_16TO8(-4), /* re10 */
8994 DRXJ_16TO8(28), /* re11 */
8995 DRXJ_16TO8(-15), /* re12 */
8996 DRXJ_16TO8(-14), /* re13 */
8997 DRXJ_16TO8(10), /* re14 */
8998 DRXJ_16TO8(1), /* re15 */
8999 DRXJ_16TO8(39), /* re16 */
9000 DRXJ_16TO8(-18), /* re17 */
9001 DRXJ_16TO8(-90), /* re18 */
9002 DRXJ_16TO8(109), /* re19 */
9003 DRXJ_16TO8(113), /* re20 */
9004 DRXJ_16TO8(-235), /* re21 */
9005 DRXJ_16TO8(-49), /* re22 */
9006 DRXJ_16TO8(359), /* re23 */
9007 DRXJ_16TO8(-79), /* re24 */
9008 DRXJ_16TO8(-459), /* re25 */
9009 DRXJ_16TO8(206), /* re26 */
9010 DRXJ_16TO8(894) /* re27 */
9011 };
9012 const u8_t dk_i_l_lp_taps_im[] = {
9013 DRXJ_16TO8(-8), /* im0 */
9014 DRXJ_16TO8(-20), /* im1 */
9015 DRXJ_16TO8(17), /* im2 */
9016 DRXJ_16TO8(-14), /* im3 */
9017 DRXJ_16TO8(-52), /* im4 */
9018 DRXJ_16TO8(4), /* im5 */
9019 DRXJ_16TO8(9), /* im6 */
9020 DRXJ_16TO8(-62), /* im7 */
9021 DRXJ_16TO8(-47), /* im8 */
9022 DRXJ_16TO8(0), /* im9 */
9023 DRXJ_16TO8(-20), /* im10 */
9024 DRXJ_16TO8(-48), /* im11 */
9025 DRXJ_16TO8(-65), /* im12 */
9026 DRXJ_16TO8(-23), /* im13 */
9027 DRXJ_16TO8(44), /* im14 */
9028 DRXJ_16TO8(-60), /* im15 */
9029 DRXJ_16TO8(-113), /* im16 */
9030 DRXJ_16TO8(92), /* im17 */
9031 DRXJ_16TO8(81), /* im18 */
9032 DRXJ_16TO8(-125), /* im19 */
9033 DRXJ_16TO8(28), /* im20 */
9034 DRXJ_16TO8(182), /* im21 */
9035 DRXJ_16TO8(35), /* im22 */
9036 DRXJ_16TO8(94), /* im23 */
9037 DRXJ_16TO8(180), /* im24 */
9038 DRXJ_16TO8(134), /* im25 */
9039 DRXJ_16TO8(657), /* im26 */
9040 DRXJ_16TO8(1023) /* im27 */
9041 };
9042 const u8_t fm_taps_re[] = {
9043 DRXJ_16TO8(0), /* re0 */
9044 DRXJ_16TO8(0), /* re1 */
9045 DRXJ_16TO8(0), /* re2 */
9046 DRXJ_16TO8(0), /* re3 */
9047 DRXJ_16TO8(0), /* re4 */
9048 DRXJ_16TO8(0), /* re5 */
9049 DRXJ_16TO8(0), /* re6 */
9050 DRXJ_16TO8(0), /* re7 */
9051 DRXJ_16TO8(0), /* re8 */
9052 DRXJ_16TO8(0), /* re9 */
9053 DRXJ_16TO8(0), /* re10 */
9054 DRXJ_16TO8(0), /* re11 */
9055 DRXJ_16TO8(0), /* re12 */
9056 DRXJ_16TO8(0), /* re13 */
9057 DRXJ_16TO8(0), /* re14 */
9058 DRXJ_16TO8(0), /* re15 */
9059 DRXJ_16TO8(0), /* re16 */
9060 DRXJ_16TO8(0), /* re17 */
9061 DRXJ_16TO8(0), /* re18 */
9062 DRXJ_16TO8(0), /* re19 */
9063 DRXJ_16TO8(0), /* re20 */
9064 DRXJ_16TO8(0), /* re21 */
9065 DRXJ_16TO8(0), /* re22 */
9066 DRXJ_16TO8(0), /* re23 */
9067 DRXJ_16TO8(0), /* re24 */
9068 DRXJ_16TO8(0), /* re25 */
9069 DRXJ_16TO8(0), /* re26 */
9070 DRXJ_16TO8(0) /* re27 */
9071 };
9072 const u8_t fm_taps_im[] = {
9073 DRXJ_16TO8(-6), /* im0 */
9074 DRXJ_16TO8(2), /* im1 */
9075 DRXJ_16TO8(14), /* im2 */
9076 DRXJ_16TO8(-38), /* im3 */
9077 DRXJ_16TO8(58), /* im4 */
9078 DRXJ_16TO8(-62), /* im5 */
9079 DRXJ_16TO8(42), /* im6 */
9080 DRXJ_16TO8(0), /* im7 */
9081 DRXJ_16TO8(-45), /* im8 */
9082 DRXJ_16TO8(73), /* im9 */
9083 DRXJ_16TO8(-65), /* im10 */
9084 DRXJ_16TO8(23), /* im11 */
9085 DRXJ_16TO8(34), /* im12 */
9086 DRXJ_16TO8(-77), /* im13 */
9087 DRXJ_16TO8(80), /* im14 */
9088 DRXJ_16TO8(-39), /* im15 */
9089 DRXJ_16TO8(-25), /* im16 */
9090 DRXJ_16TO8(78), /* im17 */
9091 DRXJ_16TO8(-90), /* im18 */
9092 DRXJ_16TO8(52), /* im19 */
9093 DRXJ_16TO8(16), /* im20 */
9094 DRXJ_16TO8(-77), /* im21 */
9095 DRXJ_16TO8(97), /* im22 */
9096 DRXJ_16TO8(-62), /* im23 */
9097 DRXJ_16TO8(-8), /* im24 */
9098 DRXJ_16TO8(75), /* im25 */
9099 DRXJ_16TO8(-100), /* im26 */
9100 DRXJ_16TO8(70) /* im27 */
9101 };
9102
9103 pI2CDeviceAddr_t devAddr = NULL;
9104 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
9105 /* parameterLen */ 0,
9106 /* resultLen */ 0,
9107 /* *parameter */ NULL,
9108 /* *result */ NULL
9109 };
9110 u16_t cmdResult = 0;
9111 u16_t cmdParam = 0;
9112 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
9113 DRXUCodeInfo_t ucodeInfo;
9114 pDRXCommonAttr_t commonAttr = NULL;
9115 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
9116 pDRXJData_t extAttr = NULL;
9117
9118 extAttr = (pDRXJData_t) demod->myExtAttr;
9119 devAddr = demod->myI2CDevAddr;
9120
9121 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
9122 commonAttr = demod->myCommonAttr;
9123
9124 /* Check if audio microcode is already uploaded */
9125 if (!(extAttr->flagAudMcUploaded)) {
9126 ucodeInfo.mcData = commonAttr->microcode;
9127 ucodeInfo.mcSize = commonAttr->microcodeSize;
9128
9129 /* Upload only audio microcode */
9130 CHK_ERROR(CtrlUCodeUpload
9131 (demod, &ucodeInfo, UCODE_UPLOAD, TRUE));
9132
9133 if (commonAttr->verifyMicrocode == TRUE) {
9134 CHK_ERROR(CtrlUCodeUpload
9135 (demod, &ucodeInfo, UCODE_VERIFY, TRUE));
9136 }
9137
9138 /* Prevent uploading audio microcode again */
9139 extAttr->flagAudMcUploaded = TRUE;
9140 }
9141 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
9142
9143 WR16(devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP);
9144 WR16(devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
9145 WR16(devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
9146 WR16(devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
9147 WR16(devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
9148 WR16(devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
9149 /* Reset ATV SCU */
9150 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
9151 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
9152 cmdSCU.parameterLen = 0;
9153 cmdSCU.resultLen = 1;
9154 cmdSCU.parameter = NULL;
9155 cmdSCU.result = &cmdResult;
9156 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
9157
9158 WR16(devAddr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE);
9159
9160 /* TODO remove AUTO/OFF patches after ucode fix. */
9161 switch (*standard) {
9162 case DRX_STANDARD_NTSC:
9163 /* NTSC */
9164 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_MN;
9165
9166 WR16(devAddr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN);
9167 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9168 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re),
9169 ((pu8_t) ntsc_taps_re));
9170 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im),
9171 ((pu8_t) ntsc_taps_im));
9172
9173 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN);
9174 WR16(devAddr, ATV_TOP_CR_CONT__A,
9175 (ATV_TOP_CR_CONT_CR_P_MN |
9176 ATV_TOP_CR_CONT_CR_D_MN | ATV_TOP_CR_CONT_CR_I_MN));
9177 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN);
9178 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN |
9179 ATV_TOP_STD_VID_POL_MN));
9180 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN);
9181
9182 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9183 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9184 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
9185 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9186 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9187 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9188 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
9189 extAttr->phaseCorrectionBypass = FALSE;
9190 extAttr->enableCVBSOutput = TRUE;
9191 break;
9192 case DRX_STANDARD_FM:
9193 /* FM */
9194 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_FM;
9195
9196 WR16(devAddr, IQM_RT_LO_INCR__A, 2994);
9197 WR16(devAddr, IQM_CF_MIDTAP__A, 0);
9198 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re),
9199 ((pu8_t) fm_taps_re));
9200 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im),
9201 ((pu8_t) fm_taps_im));
9202 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM |
9203 ATV_TOP_STD_VID_POL_FM));
9204 WR16(devAddr, ATV_TOP_MOD_CONTROL__A, 0);
9205 WR16(devAddr, ATV_TOP_CR_CONT__A, 0);
9206
9207 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9208 (SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW |
9209 SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM));
9210 WR16(devAddr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF);
9211 extAttr->phaseCorrectionBypass = TRUE;
9212 extAttr->enableCVBSOutput = FALSE;
9213 break;
9214 case DRX_STANDARD_PAL_SECAM_BG:
9215 /* PAL/SECAM B/G */
9216 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_B;
9217
9218 WR16(devAddr, IQM_RT_LO_INCR__A, 1820); /* TODO check with IS */
9219 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9220 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re),
9221 ((pu8_t) bg_taps_re));
9222 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im),
9223 ((pu8_t) bg_taps_im));
9224 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG);
9225 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG);
9226 WR16(devAddr, ATV_TOP_CR_CONT__A,
9227 (ATV_TOP_CR_CONT_CR_P_BG |
9228 ATV_TOP_CR_CONT_CR_D_BG | ATV_TOP_CR_CONT_CR_I_BG));
9229 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG);
9230 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG |
9231 ATV_TOP_STD_VID_POL_BG));
9232 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9233 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9234 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
9235 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9236 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9237 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9238 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
9239 extAttr->phaseCorrectionBypass = FALSE;
9240 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
9241 extAttr->enableCVBSOutput = TRUE;
9242 break;
9243 case DRX_STANDARD_PAL_SECAM_DK:
9244 /* PAL/SECAM D/K */
9245 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_DK;
9246
9247 WR16(devAddr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9248 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9249 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
9250 ((pu8_t) dk_i_l_lp_taps_re));
9251 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
9252 ((pu8_t) dk_i_l_lp_taps_im));
9253 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK);
9254 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK);
9255 WR16(devAddr, ATV_TOP_CR_CONT__A,
9256 (ATV_TOP_CR_CONT_CR_P_DK |
9257 ATV_TOP_CR_CONT_CR_D_DK | ATV_TOP_CR_CONT_CR_I_DK));
9258 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK);
9259 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK |
9260 ATV_TOP_STD_VID_POL_DK));
9261 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9262 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9263 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
9264 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9265 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9266 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9267 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK);
9268 extAttr->phaseCorrectionBypass = FALSE;
9269 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
9270 extAttr->enableCVBSOutput = TRUE;
9271 break;
9272 case DRX_STANDARD_PAL_SECAM_I:
9273 /* PAL/SECAM I */
9274 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_I;
9275
9276 WR16(devAddr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9277 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9278 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
9279 ((pu8_t) dk_i_l_lp_taps_re));
9280 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
9281 ((pu8_t) dk_i_l_lp_taps_im));
9282 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I);
9283 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I);
9284 WR16(devAddr, ATV_TOP_CR_CONT__A,
9285 (ATV_TOP_CR_CONT_CR_P_I |
9286 ATV_TOP_CR_CONT_CR_D_I | ATV_TOP_CR_CONT_CR_I_I));
9287 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I);
9288 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I |
9289 ATV_TOP_STD_VID_POL_I));
9290 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9291 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9292 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
9293 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9294 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9295 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9296 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I);
9297 extAttr->phaseCorrectionBypass = FALSE;
9298 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
9299 extAttr->enableCVBSOutput = TRUE;
9300 break;
9301 case DRX_STANDARD_PAL_SECAM_L:
9302 /* PAL/SECAM L with negative modulation */
9303 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_L;
9304
9305 WR16(devAddr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9306 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L);
9307 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9308 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
9309 ((pu8_t) dk_i_l_lp_taps_re));
9310 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
9311 ((pu8_t) dk_i_l_lp_taps_im));
9312 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, 0x2); /* TODO check with IS */
9313 WR16(devAddr, ATV_TOP_CR_CONT__A,
9314 (ATV_TOP_CR_CONT_CR_P_L |
9315 ATV_TOP_CR_CONT_CR_D_L | ATV_TOP_CR_CONT_CR_I_L));
9316 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L);
9317 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L |
9318 ATV_TOP_STD_VID_POL_L));
9319 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9320 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
9321 SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
9322 SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW));
9323 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9324 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9325 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9326 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
9327 extAttr->phaseCorrectionBypass = FALSE;
9328 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_USER;
9329 extAttr->atvIfAgcCfg.outputLevel = extAttr->atvRfAgcCfg.top;
9330 extAttr->enableCVBSOutput = TRUE;
9331 break;
9332 case DRX_STANDARD_PAL_SECAM_LP:
9333 /* PAL/SECAM L with positive modulation */
9334 cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_LP;
9335
9336 WR16(devAddr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP);
9337 WR16(devAddr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9338 WR16(devAddr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9339 WRB(devAddr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
9340 ((pu8_t) dk_i_l_lp_taps_re));
9341 WRB(devAddr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
9342 ((pu8_t) dk_i_l_lp_taps_im));
9343 WR16(devAddr, ATV_TOP_CR_AMP_TH__A, 0x2); /* TODO check with IS */
9344 WR16(devAddr, ATV_TOP_CR_CONT__A,
9345 (ATV_TOP_CR_CONT_CR_P_LP |
9346 ATV_TOP_CR_CONT_CR_D_LP | ATV_TOP_CR_CONT_CR_I_LP));
9347 WR16(devAddr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP);
9348 WR16(devAddr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP |
9349 ATV_TOP_STD_VID_POL_LP));
9350 WR16(devAddr, SCU_RAM_ATV_AGC_MODE__A,
9351 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
9352 SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
9353 SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW));
9354 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9355 WR16(devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9356 WR16(devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
9357 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
9358 extAttr->phaseCorrectionBypass = FALSE;
9359 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_USER;
9360 extAttr->atvIfAgcCfg.outputLevel = extAttr->atvRfAgcCfg.top;
9361 extAttr->enableCVBSOutput = TRUE;
9362 break;
9363 default:
9364 return (DRX_STS_ERROR);
9365 }
9366
9367 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
9368 if (extAttr->hasLNA == FALSE) {
9369 WR16(devAddr, IQM_AF_AMUX__A, 0x01);
9370 }
9371
9372 WR16(devAddr, SCU_RAM_ATV_STANDARD__A, 0x002);
9373 WR16(devAddr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV);
9374 WR16(devAddr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV);
9375 WR16(devAddr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV);
9376 CHK_ERROR(CtrlSetCfgPreSaw(demod, &(extAttr->atvPreSawCfg)));
9377 WR16(devAddr, IQM_AF_AGC_IF__A, 10248);
9378
9379 extAttr->iqmRcRateOfs = 0x00200000L;
9380 WR32(devAddr, IQM_RC_RATE_OFS_LO__A, extAttr->iqmRcRateOfs);
9381 WR16(devAddr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF);
9382 WR16(devAddr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV);
9383
9384 WR16(devAddr, IQM_RT_ACTIVE__A, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON |
9385 IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON);
9386
9387 WR16(devAddr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M);
9388 WR16(devAddr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M);
9389 /* default: SIF in standby */
9390 WR16(devAddr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN);
9391 WR16(devAddr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE);
9392
9393 WR16(devAddr, SCU_RAM_ATV_SIF_GAIN__A, 0x080);
9394 WR16(devAddr, SCU_RAM_ATV_FAGC_TH_RED__A, 10);
9395 WR16(devAddr, SCU_RAM_ATV_AAGC_CNT__A, 7);
9396 WR16(devAddr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225);
9397 WR16(devAddr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547);
9398 WR16(devAddr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20);
9399 WR16(devAddr, SCU_RAM_ATV_LOCK__A, 0);
9400
9401 WR16(devAddr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE);
9402 WR16(devAddr, SCU_RAM_ATV_BPC_KI_MIN__A, 531);
9403 WR16(devAddr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061);
9404 WR16(devAddr, SCU_RAM_ATV_BP_REF_MIN__A, 100);
9405 WR16(devAddr, SCU_RAM_ATV_BP_REF_MAX__A, 260);
9406 WR16(devAddr, SCU_RAM_ATV_BP_LVL__A, 0);
9407 WR16(devAddr, SCU_RAM_ATV_AMS_MAX__A, 0);
9408 WR16(devAddr, SCU_RAM_ATV_AMS_MIN__A, 2047);
9409 WR16(devAddr, SCU_RAM_GPIO__A, 0);
9410
9411 /* Override reset values with current shadow settings */
9412 CHK_ERROR(AtvUpdateConfig(demod, TRUE));
9413
9414 /* Configure/restore AGC settings */
9415 CHK_ERROR(InitAGC(demod));
9416 CHK_ERROR(SetAgcIf(demod, &(extAttr->atvIfAgcCfg), FALSE));
9417 CHK_ERROR(SetAgcRf(demod, &(extAttr->atvRfAgcCfg), FALSE));
9418 CHK_ERROR(CtrlSetCfgPreSaw(demod, &(extAttr->atvPreSawCfg)));
9419
9420 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
9421 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
9422 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
9423 cmdSCU.parameterLen = 1;
9424 cmdSCU.resultLen = 1;
9425 cmdSCU.parameter = &cmdParam;
9426 cmdSCU.result = &cmdResult;
9427 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
9428
9429 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
9430 if (extAttr->mfx == 0x03) {
9431 WR16(devAddr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0);
9432 } else {
9433 WR16(devAddr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1);
9434 WR16(devAddr, SCU_RAM_ATV_IIR_CRIT__A, 225);
9435 }
9436
9437 return (DRX_STS_OK);
9438 rw_error:
9439 return (DRX_STS_ERROR);
9440 }
9441 #endif
9442
9443 /* -------------------------------------------------------------------------- */
9444
9445 #ifndef DRXJ_DIGITAL_ONLY
9446 /**
9447 * \fn DRXStatus_t SetATVChannel ()
9448 * \brief Set ATV channel.
9449 * \param demod: instance of demod.
9450 * \return DRXStatus_t.
9451 *
9452 * Not much needs to be done here, only start the SCU for NTSC/FM.
9453 * Mirrored channels are not expected in the RF domain, so IQM FS setting
9454 * doesn't need to be remembered.
9455 * The channel->mirror parameter is therefor ignored.
9456 *
9457 */
9458 static DRXStatus_t
9459 SetATVChannel(pDRXDemodInstance_t demod,
9460 DRXFrequency_t tunerFreqOffset,
9461 pDRXChannel_t channel, DRXStandard_t standard)
9462 {
9463 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
9464 /* parameterLen */ 0,
9465 /* resultLen */ 0,
9466 /* parameter */ NULL,
9467 /* result */ NULL
9468 };
9469 u16_t cmdResult = 0;
9470 pDRXJData_t extAttr = NULL;
9471 pI2CDeviceAddr_t devAddr = NULL;
9472
9473 devAddr = demod->myI2CDevAddr;
9474 extAttr = (pDRXJData_t) demod->myExtAttr;
9475
9476 /*
9477 Program frequency shifter
9478 No need to account for mirroring on RF
9479 */
9480 if (channel->mirror == DRX_MIRROR_AUTO) {
9481 extAttr->mirror = DRX_MIRROR_NO;
9482 } else {
9483 extAttr->mirror = channel->mirror;
9484 }
9485
9486 CHK_ERROR(SetFrequency(demod, channel, tunerFreqOffset));
9487 WR16(devAddr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE);
9488
9489 /* Start ATV SCU */
9490 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
9491 SCU_RAM_COMMAND_CMD_DEMOD_START;
9492 cmdSCU.parameterLen = 0;
9493 cmdSCU.resultLen = 1;
9494 cmdSCU.parameter = NULL;
9495 cmdSCU.result = &cmdResult;
9496 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
9497
9498 /* if ( (extAttr->standard == DRX_STANDARD_FM) && (extAttr->flagSetAUDdone == TRUE) )
9499 {
9500 extAttr->detectedRDS = (Bool_t)FALSE;
9501 }*/
9502
9503 return (DRX_STS_OK);
9504 rw_error:
9505 return (DRX_STS_ERROR);
9506 }
9507 #endif
9508
9509 /* -------------------------------------------------------------------------- */
9510
9511 /**
9512 * \fn DRXStatus_t GetATVChannel ()
9513 * \brief Set ATV channel.
9514 * \param demod: instance of demod.
9515 * \param channel: pointer to channel data.
9516 * \param standard: NTSC or FM.
9517 * \return DRXStatus_t.
9518 *
9519 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
9520 * Computes the frequency offset in te RF domain and adds it to
9521 * channel->frequency. Determines the value for channel->bandwidth.
9522 *
9523 */
9524 #ifndef DRXJ_DIGITAL_ONLY
9525 static DRXStatus_t
9526 GetATVChannel(pDRXDemodInstance_t demod,
9527 pDRXChannel_t channel, DRXStandard_t standard)
9528 {
9529 DRXFrequency_t offset = 0;
9530 pI2CDeviceAddr_t devAddr = NULL;
9531 pDRXJData_t extAttr = NULL;
9532
9533 devAddr = demod->myI2CDevAddr;
9534 extAttr = (pDRXJData_t) demod->myExtAttr;
9535
9536 /* Bandwidth */
9537 channel->bandwidth = ((pDRXJData_t) demod->myExtAttr)->currBandwidth;
9538
9539 switch (standard) {
9540 case DRX_STANDARD_NTSC:
9541 case DRX_STANDARD_PAL_SECAM_BG:
9542 case DRX_STANDARD_PAL_SECAM_DK:
9543 case DRX_STANDARD_PAL_SECAM_I:
9544 case DRX_STANDARD_PAL_SECAM_L:
9545 {
9546 u16_t measuredOffset = 0;
9547
9548 /* get measured frequency offset */
9549 RR16(devAddr, ATV_TOP_CR_FREQ__A, &measuredOffset);
9550 /* Signed 8 bit register => sign extension needed */
9551 if ((measuredOffset & 0x0080) != 0) {
9552 /* sign extension */
9553 measuredOffset |= 0xFF80;
9554 }
9555 offset +=
9556 (DRXFrequency_t) (((s16_t) measuredOffset) * 10);
9557 break;
9558 }
9559 case DRX_STANDARD_PAL_SECAM_LP:
9560 {
9561 u16_t measuredOffset = 0;
9562
9563 /* get measured frequency offset */
9564 RR16(devAddr, ATV_TOP_CR_FREQ__A, &measuredOffset);
9565 /* Signed 8 bit register => sign extension needed */
9566 if ((measuredOffset & 0x0080) != 0) {
9567 /* sign extension */
9568 measuredOffset |= 0xFF80;
9569 }
9570 offset -=
9571 (DRXFrequency_t) (((s16_t) measuredOffset) * 10);
9572 }
9573 break;
9574 case DRX_STANDARD_FM:
9575 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
9576 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
9577 */
9578 /* No bandwidth know for FM */
9579 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
9580 break;
9581 default:
9582 return (DRX_STS_ERROR);
9583 }
9584
9585 channel->frequency -= offset;
9586
9587 return (DRX_STS_OK);
9588 rw_error:
9589 return (DRX_STS_ERROR);
9590 }
9591
9592 /* -------------------------------------------------------------------------- */
9593 /**
9594 * \fn DRXStatus_t GetAtvSigStrength()
9595 * \brief Retrieve signal strength for ATV & FM.
9596 * \param devmod Pointer to demodulator instance.
9597 * \param sigQuality Pointer to signal strength data; range 0, .. , 100.
9598 * \return DRXStatus_t.
9599 * \retval DRX_STS_OK sigStrength contains valid data.
9600 * \retval DRX_STS_ERROR Erroneous data, sigStrength equals 0.
9601 *
9602 * Taking into account:
9603 * * digital gain
9604 * * IF gain (not implemented yet, waiting for IF gain control by ucode)
9605 * * RF gain
9606 *
9607 * All weights (digital, if, rf) must add up to 100.
9608 *
9609 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
9610 * is not used ?
9611 */
9612 static DRXStatus_t
9613 GetAtvSigStrength(pDRXDemodInstance_t demod, pu16_t sigStrength)
9614 {
9615 pI2CDeviceAddr_t devAddr = NULL;
9616 pDRXJData_t extAttr = NULL;
9617
9618 /* All weights must add up to 100 (%)
9619 TODO: change weights when IF ctrl is available */
9620 u32_t digitalWeight = 50; /* 0 .. 100 */
9621 u32_t rfWeight = 50; /* 0 .. 100 */
9622 u32_t ifWeight = 0; /* 0 .. 100 */
9623
9624 u16_t digitalCurrGain = 0;
9625 u32_t digitalMaxGain = 0;
9626 u32_t digitalMinGain = 0;
9627 u16_t rfCurrGain = 0;
9628 u32_t rfMaxGain = 0x800; /* taken from ucode */
9629 u32_t rfMinGain = 0x7fff;
9630 u16_t ifCurrGain = 0;
9631 u32_t ifMaxGain = 0x800; /* taken from ucode */
9632 u32_t ifMinGain = 0x7fff;
9633
9634 u32_t digitalStrength = 0; /* 0.. 100 */
9635 u32_t rfStrength = 0; /* 0.. 100 */
9636 u32_t ifStrength = 0; /* 0.. 100 */
9637
9638 devAddr = demod->myI2CDevAddr;
9639 extAttr = (pDRXJData_t) demod->myExtAttr;
9640
9641 *sigStrength = 0;
9642
9643 switch (extAttr->standard) {
9644 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
9645 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
9646 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
9647 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
9648 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
9649 case DRX_STANDARD_NTSC:
9650 SARR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, &digitalCurrGain);
9651 digitalMaxGain = 22512; /* taken from ucode */
9652 digitalMinGain = 2400; /* taken from ucode */
9653 break;
9654 case DRX_STANDARD_FM:
9655 SARR16(devAddr, SCU_RAM_ATV_SIF_GAIN__A, &digitalCurrGain);
9656 digitalMaxGain = 0x4ff; /* taken from ucode */
9657 digitalMinGain = 0; /* taken from ucode */
9658 break;
9659 default:
9660 return (DRX_STS_ERROR);
9661 break;
9662 }
9663 RR16(devAddr, IQM_AF_AGC_RF__A, &rfCurrGain);
9664 RR16(devAddr, IQM_AF_AGC_IF__A, &ifCurrGain);
9665
9666 /* clipping */
9667 if (digitalCurrGain >= digitalMaxGain)
9668 digitalCurrGain = (u16_t) digitalMaxGain;
9669 if (digitalCurrGain <= digitalMinGain)
9670 digitalCurrGain = (u16_t) digitalMinGain;
9671 if (ifCurrGain <= ifMaxGain)
9672 ifCurrGain = (u16_t) ifMaxGain;
9673 if (ifCurrGain >= ifMinGain)
9674 ifCurrGain = (u16_t) ifMinGain;
9675 if (rfCurrGain <= rfMaxGain)
9676 rfCurrGain = (u16_t) rfMaxGain;
9677 if (rfCurrGain >= rfMinGain)
9678 rfCurrGain = (u16_t) rfMinGain;
9679
9680 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
9681 of clipping at ADC */
9682
9683 /* Compute signal strength (in %) per "gain domain" */
9684
9685 /* Digital gain */
9686 /* TODO: ADC clipping not handled */
9687 digitalStrength = (100 * (digitalMaxGain - (u32_t) digitalCurrGain)) /
9688 (digitalMaxGain - digitalMinGain);
9689
9690 /* TODO: IF gain not implemented yet in microcode, check after impl. */
9691 ifStrength = (100 * ((u32_t) ifCurrGain - ifMaxGain)) /
9692 (ifMinGain - ifMaxGain);
9693
9694 /* Rf gain */
9695 /* TODO: ADC clipping not handled */
9696 rfStrength = (100 * ((u32_t) rfCurrGain - rfMaxGain)) /
9697 (rfMinGain - rfMaxGain);
9698
9699 /* Compute a weighted signal strength (in %) */
9700 *sigStrength = (u16_t) (digitalWeight * digitalStrength +
9701 rfWeight * rfStrength + ifWeight * ifStrength);
9702 *sigStrength /= 100;
9703
9704 return (DRX_STS_OK);
9705 rw_error:
9706 return (DRX_STS_ERROR);
9707 }
9708
9709 /* -------------------------------------------------------------------------- */
9710 /**
9711 * \fn DRXStatus_t AtvSigQuality()
9712 * \brief Retrieve signal quality indication for ATV.
9713 * \param devmod Pointer to demodulator instance.
9714 * \param sigQuality Pointer to signal quality structure.
9715 * \return DRXStatus_t.
9716 * \retval DRX_STS_OK sigQuality contains valid data.
9717 * \retval DRX_STS_ERROR Erroneous data, sigQuality indicator equals 0.
9718 *
9719 *
9720 */
9721 static DRXStatus_t
9722 AtvSigQuality(pDRXDemodInstance_t demod, pDRXSigQuality_t sigQuality)
9723 {
9724 pI2CDeviceAddr_t devAddr = NULL;
9725 u16_t qualityIndicator = 0;
9726
9727 devAddr = demod->myI2CDevAddr;
9728
9729 /* defined values for fields not used */
9730 sigQuality->MER = 0;
9731 sigQuality->preViterbiBER = 0;
9732 sigQuality->postViterbiBER = 0;
9733 sigQuality->scaleFactorBER = 1;
9734 sigQuality->packetError = 0;
9735 sigQuality->postReedSolomonBER = 0;
9736
9737 /*
9738 Mapping:
9739 0x000..0x080: strong signal => 80% .. 100%
9740 0x080..0x700: weak signal => 30% .. 80%
9741 0x700..0x7ff: no signal => 0% .. 30%
9742 */
9743
9744 SARR16(devAddr, SCU_RAM_ATV_CR_LOCK__A, &qualityIndicator);
9745 qualityIndicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
9746 if (qualityIndicator <= 0x80) {
9747 sigQuality->indicator =
9748 80 + ((20 * (0x80 - qualityIndicator)) / 0x80);
9749 } else if (qualityIndicator <= 0x700) {
9750 sigQuality->indicator = 30 +
9751 ((50 * (0x700 - qualityIndicator)) / (0x700 - 0x81));
9752 } else {
9753 sigQuality->indicator =
9754 (30 * (0x7FF - qualityIndicator)) / (0x7FF - 0x701);
9755 }
9756
9757 return (DRX_STS_OK);
9758 rw_error:
9759 return (DRX_STS_ERROR);
9760 }
9761 #endif /* DRXJ_DIGITAL_ONLY */
9762
9763 /*============================================================================*/
9764 /*== END ATV DATAPATH FUNCTIONS ==*/
9765 /*============================================================================*/
9766
9767 #ifndef DRXJ_EXCLUDE_AUDIO
9768 /*===========================================================================*/
9769 /*===========================================================================*/
9770 /*== AUDIO DATAPATH FUNCTIONS ==*/
9771 /*===========================================================================*/
9772 /*===========================================================================*/
9773
9774 /*
9775 * \brief Power up AUD.
9776 * \param demod instance of demodulator
9777 * \return DRXStatus_t.
9778 *
9779 */
9780 static DRXStatus_t PowerUpAud(pDRXDemodInstance_t demod, Bool_t setStandard)
9781 {
9782 DRXAudStandard_t audStandard = DRX_AUD_STANDARD_AUTO;
9783 pI2CDeviceAddr_t devAddr = NULL;
9784
9785 devAddr = demod->myI2CDevAddr;
9786
9787 WR16(devAddr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE);
9788 /* setup TR interface: R/W mode, fifosize=8 */
9789 WR16(devAddr, AUD_TOP_TR_MDE__A, 8);
9790 WR16(devAddr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE);
9791
9792 if (setStandard == TRUE) {
9793 CHK_ERROR(AUDCtrlSetStandard(demod, &audStandard));
9794 }
9795
9796 return DRX_STS_OK;
9797 rw_error:
9798 return DRX_STS_ERROR;
9799 }
9800
9801 /*============================================================================*/
9802
9803 /**
9804 * \brief Power up AUD.
9805 * \param demod instance of demodulator
9806 * \return DRXStatus_t.
9807 *
9808 */
9809 static DRXStatus_t PowerDownAud(pDRXDemodInstance_t demod)
9810 {
9811 pI2CDeviceAddr_t devAddr = NULL;
9812 pDRXJData_t extAttr = NULL;
9813
9814 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
9815 extAttr = (pDRXJData_t) demod->myExtAttr;
9816
9817 WR16(devAddr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
9818
9819 extAttr->audData.audioIsActive = FALSE;
9820
9821 return DRX_STS_OK;
9822 rw_error:
9823 return DRX_STS_ERROR;
9824 }
9825
9826 /*============================================================================*/
9827 /**
9828 * \brief Get Modus data from audio RAM
9829 * \param demod instance of demodulator
9830 * \param pointer to modus
9831 * \return DRXStatus_t.
9832 *
9833 */
9834 static DRXStatus_t AUDGetModus(pDRXDemodInstance_t demod, pu16_t modus)
9835 {
9836 pI2CDeviceAddr_t devAddr = NULL;
9837 pDRXJData_t extAttr = NULL;
9838
9839 u16_t rModus = 0;
9840 u16_t rModusHi = 0;
9841 u16_t rModusLo = 0;
9842
9843 if (modus == NULL) {
9844 return DRX_STS_INVALID_ARG;
9845 }
9846
9847 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
9848 extAttr = (pDRXJData_t) demod->myExtAttr;
9849
9850 /* power up */
9851 if (extAttr->audData.audioIsActive == FALSE) {
9852 CHK_ERROR(PowerUpAud(demod, TRUE));
9853 extAttr->audData.audioIsActive = TRUE;
9854 }
9855
9856 /* Modus register is combined in to RAM location */
9857 RR16(devAddr, AUD_DEM_RAM_MODUS_HI__A, &rModusHi);
9858 RR16(devAddr, AUD_DEM_RAM_MODUS_LO__A, &rModusLo);
9859
9860 rModus = ((rModusHi << 12) & AUD_DEM_RAM_MODUS_HI__M)
9861 | (((rModusLo & AUD_DEM_RAM_MODUS_LO__M)));
9862
9863 *modus = rModus;
9864
9865 return DRX_STS_OK;
9866 rw_error:
9867 return DRX_STS_ERROR;
9868
9869 }
9870
9871 /*============================================================================*/
9872 /**
9873 * \brief Get audio RDS dat
9874 * \param demod instance of demodulator
9875 * \param pointer to DRXCfgAudRDS_t
9876 * \return DRXStatus_t.
9877 *
9878 */
9879 static DRXStatus_t
9880 AUDCtrlGetCfgRDS(pDRXDemodInstance_t demod, pDRXCfgAudRDS_t status)
9881 {
9882 pI2CDeviceAddr_t addr = NULL;
9883 pDRXJData_t extAttr = NULL;
9884
9885 u16_t rRDSArrayCntInit = 0;
9886 u16_t rRDSArrayCntCheck = 0;
9887 u16_t rRDSData = 0;
9888 u16_t RDSDataCnt = 0;
9889
9890 addr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
9891 extAttr = (pDRXJData_t) demod->myExtAttr;
9892
9893 if (status == NULL) {
9894 return DRX_STS_INVALID_ARG;
9895 }
9896
9897 /* power up */
9898 if (extAttr->audData.audioIsActive == FALSE) {
9899 CHK_ERROR(PowerUpAud(demod, TRUE));
9900 extAttr->audData.audioIsActive = TRUE;
9901 }
9902
9903 status->valid = FALSE;
9904
9905 RR16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &rRDSArrayCntInit);
9906
9907 if (rRDSArrayCntInit ==
9908 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
9909 /* invalid data */
9910 return DRX_STS_OK;
9911 }
9912
9913 if (extAttr->audData.rdsDataCounter == rRDSArrayCntInit) {
9914 /* no new data */
9915 return DRX_STS_OK;
9916 }
9917
9918 /* RDS is detected, as long as FM radio is selected assume
9919 RDS will be available */
9920 extAttr->audData.rdsDataPresent = TRUE;
9921
9922 /* new data */
9923 /* read the data */
9924 for (RDSDataCnt = 0; RDSDataCnt < AUD_RDS_ARRAY_SIZE; RDSDataCnt++) {
9925 RR16(addr, AUD_DEM_RD_RDS_DATA__A, &rRDSData);
9926 status->data[RDSDataCnt] = rRDSData;
9927 }
9928
9929 RR16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &rRDSArrayCntCheck);
9930
9931 if (rRDSArrayCntCheck == rRDSArrayCntInit) {
9932 status->valid = TRUE;
9933 extAttr->audData.rdsDataCounter = rRDSArrayCntCheck;
9934 }
9935
9936 return DRX_STS_OK;
9937 rw_error:
9938 return DRX_STS_ERROR;
9939 }
9940
9941 /*============================================================================*/
9942 /**
9943 * \brief Get the current audio carrier detection status
9944 * \param demod instance of demodulator
9945 * \param pointer to AUDCtrlGetStatus
9946 * \return DRXStatus_t.
9947 *
9948 */
9949 static DRXStatus_t
9950 AUDCtrlGetCarrierDetectStatus(pDRXDemodInstance_t demod, pDRXAudStatus_t status)
9951 {
9952 pDRXJData_t extAttr = NULL;
9953 pI2CDeviceAddr_t devAddr = NULL;
9954
9955 u16_t rData = 0;
9956
9957 if (status == NULL) {
9958 return DRX_STS_INVALID_ARG;
9959 }
9960
9961 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
9962 extAttr = (pDRXJData_t) demod->myExtAttr;
9963
9964 /* power up */
9965 if (extAttr->audData.audioIsActive == FALSE) {
9966 CHK_ERROR(PowerUpAud(demod, TRUE));
9967 extAttr->audData.audioIsActive = TRUE;
9968 }
9969
9970 /* initialize the variables */
9971 status->carrierA = FALSE;
9972 status->carrierB = FALSE;
9973 status->nicamStatus = DRX_AUD_NICAM_NOT_DETECTED;
9974 status->sap = FALSE;
9975 status->stereo = FALSE;
9976
9977 /* read stereo sound mode indication */
9978 RR16(devAddr, AUD_DEM_RD_STATUS__A, &rData);
9979
9980 /* carrier a detected */
9981 if ((rData & AUD_DEM_RD_STATUS_STAT_CARR_A__M) ==
9982 AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED) {
9983 status->carrierA = TRUE;
9984 }
9985
9986 /* carrier b detected */
9987 if ((rData & AUD_DEM_RD_STATUS_STAT_CARR_B__M) ==
9988 AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED) {
9989 status->carrierB = TRUE;
9990 }
9991 /* nicam detected */
9992 if ((rData & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
9993 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
9994 if ((rData & AUD_DEM_RD_STATUS_BAD_NICAM__M) ==
9995 AUD_DEM_RD_STATUS_BAD_NICAM_OK) {
9996 status->nicamStatus = DRX_AUD_NICAM_DETECTED;
9997 } else {
9998 status->nicamStatus = DRX_AUD_NICAM_BAD;
9999 }
10000 }
10001
10002 /* audio mode bilingual or SAP detected */
10003 if ((rData & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) ==
10004 AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP) {
10005 status->sap = TRUE;
10006 }
10007
10008 /* stereo detected */
10009 if ((rData & AUD_DEM_RD_STATUS_STAT_STEREO__M) ==
10010 AUD_DEM_RD_STATUS_STAT_STEREO_STEREO) {
10011 status->stereo = TRUE;
10012 }
10013
10014 return DRX_STS_OK;
10015 rw_error:
10016 return DRX_STS_ERROR;
10017 }
10018
10019 /*============================================================================*/
10020 /**
10021 * \brief Get the current audio status parameters
10022 * \param demod instance of demodulator
10023 * \param pointer to AUDCtrlGetStatus
10024 * \return DRXStatus_t.
10025 *
10026 */
10027 static DRXStatus_t
10028 AUDCtrlGetStatus(pDRXDemodInstance_t demod, pDRXAudStatus_t status)
10029 {
10030 pDRXJData_t extAttr = NULL;
10031 pI2CDeviceAddr_t devAddr = NULL;
10032 DRXCfgAudRDS_t rds = { FALSE, {0} };
10033 u16_t rData = 0;
10034
10035 if (status == NULL) {
10036 return DRX_STS_INVALID_ARG;
10037 }
10038
10039 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
10040 extAttr = (pDRXJData_t) demod->myExtAttr;
10041
10042 /* carrier detection */
10043 CHK_ERROR(AUDCtrlGetCarrierDetectStatus(demod, status));
10044
10045 /* rds data */
10046 status->rds = FALSE;
10047 CHK_ERROR(AUDCtrlGetCfgRDS(demod, &rds));
10048 status->rds = extAttr->audData.rdsDataPresent;
10049
10050 /* fmIdent */
10051 RR16(devAddr, AUD_DSP_RD_FM_IDENT_VALUE__A, &rData);
10052 rData >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
10053 status->fmIdent = (s8_t) rData;
10054
10055 return DRX_STS_OK;
10056 rw_error:
10057 return DRX_STS_ERROR;
10058 }
10059
10060 /*============================================================================*/
10061 /**
10062 * \brief Get the current volume settings
10063 * \param demod instance of demodulator
10064 * \param pointer to DRXCfgAudVolume_t
10065 * \return DRXStatus_t.
10066 *
10067 */
10068 static DRXStatus_t
10069 AUDCtrlGetCfgVolume(pDRXDemodInstance_t demod, pDRXCfgAudVolume_t volume)
10070 {
10071 pI2CDeviceAddr_t devAddr = NULL;
10072 pDRXJData_t extAttr = NULL;
10073
10074 u16_t rVolume = 0;
10075 u16_t rAVC = 0;
10076 u16_t rStrengthLeft = 0;
10077 u16_t rStrengthRight = 0;
10078
10079 if (volume == NULL) {
10080 return DRX_STS_INVALID_ARG;
10081 }
10082
10083 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
10084 extAttr = (pDRXJData_t) demod->myExtAttr;
10085
10086 /* power up */
10087 if (extAttr->audData.audioIsActive == FALSE) {
10088 CHK_ERROR(PowerUpAud(demod, TRUE));
10089 extAttr->audData.audioIsActive = TRUE;
10090 }
10091
10092 /* volume */
10093 volume->mute = extAttr->audData.volume.mute;
10094 RR16(devAddr, AUD_DSP_WR_VOLUME__A, &rVolume);
10095 if (rVolume == 0) {
10096 volume->mute = TRUE;
10097 volume->volume = extAttr->audData.volume.volume;
10098 } else {
10099 volume->mute = FALSE;
10100 volume->volume = ((rVolume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
10101 AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
10102 AUD_VOLUME_ZERO_DB;
10103 if (volume->volume < AUD_VOLUME_DB_MIN) {
10104 volume->volume = AUD_VOLUME_DB_MIN;
10105 }
10106 if (volume->volume > AUD_VOLUME_DB_MAX) {
10107 volume->volume = AUD_VOLUME_DB_MAX;
10108 }
10109 }
10110
10111 /* automatic volume control */
10112 RR16(devAddr, AUD_DSP_WR_AVC__A, &rAVC);
10113
10114 if ((rAVC & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF)
10115 {
10116 volume->avcMode = DRX_AUD_AVC_OFF;
10117 } else {
10118 switch (rAVC & AUD_DSP_WR_AVC_AVC_DECAY__M) {
10119 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
10120 volume->avcMode = DRX_AUD_AVC_DECAYTIME_20MS;
10121 break;
10122 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
10123 volume->avcMode = DRX_AUD_AVC_DECAYTIME_8S;
10124 break;
10125 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
10126 volume->avcMode = DRX_AUD_AVC_DECAYTIME_4S;
10127 break;
10128 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
10129 volume->avcMode = DRX_AUD_AVC_DECAYTIME_2S;
10130 break;
10131 default:
10132 return DRX_STS_ERROR;
10133 break;
10134 }
10135 }
10136
10137 /* max attenuation */
10138 switch (rAVC & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
10139 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
10140 volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_12DB;
10141 break;
10142 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
10143 volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_18DB;
10144 break;
10145 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
10146 volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_24DB;
10147 break;
10148 default:
10149 return DRX_STS_ERROR;
10150 break;
10151 }
10152
10153 /* max gain */
10154 switch (rAVC & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
10155 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
10156 volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_0DB;
10157 break;
10158 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
10159 volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_6DB;
10160 break;
10161 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
10162 volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_12DB;
10163 break;
10164 default:
10165 return DRX_STS_ERROR;
10166 break;
10167 }
10168
10169 /* reference level */
10170 volume->avcRefLevel = (u16_t) ((rAVC & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
10171 AUD_DSP_WR_AVC_AVC_REF_LEV__B);
10172
10173 /* read qpeak registers and calculate strength of left and right carrier */
10174 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
10175 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
10176 /* left carrier */
10177
10178 /* QP vaues */
10179 /* left carrier */
10180 RR16(devAddr, AUD_DSP_RD_QPEAK_L__A, &rStrengthLeft);
10181 volume->strengthLeft = (((s16_t) Log10Times100(rStrengthLeft)) -
10182 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
10183
10184 /* right carrier */
10185 RR16(devAddr, AUD_DSP_RD_QPEAK_R__A, &rStrengthRight);
10186 volume->strengthRight = (((s16_t) Log10Times100(rStrengthRight)) -
10187 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
10188
10189 return DRX_STS_OK;
10190 rw_error:
10191 return DRX_STS_ERROR;
10192 }
10193
10194 /*============================================================================*/
10195 /**
10196 * \brief Set the current volume settings
10197 * \param demod instance of demodulator
10198 * \param pointer to DRXCfgAudVolume_t
10199 * \return DRXStatus_t.
10200 *
10201 */
10202 static DRXStatus_t
10203 AUDCtrlSetCfgVolume(pDRXDemodInstance_t demod, pDRXCfgAudVolume_t volume)
10204 {
10205 pI2CDeviceAddr_t devAddr = NULL;
10206 pDRXJData_t extAttr = NULL;
10207
10208 u16_t wVolume = 0;
10209 u16_t wAVC = 0;
10210
10211 if (volume == NULL) {
10212 return DRX_STS_INVALID_ARG;
10213 }
10214
10215 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
10216 extAttr = (pDRXJData_t) demod->myExtAttr;
10217
10218 /* power up */
10219 if (extAttr->audData.audioIsActive == FALSE) {
10220 CHK_ERROR(PowerUpAud(demod, TRUE));
10221 extAttr->audData.audioIsActive = TRUE;
10222 }
10223
10224 /* volume */
10225 /* volume range from -60 to 12 (expressed in dB) */
10226 if ((volume->volume < AUD_VOLUME_DB_MIN) ||
10227 (volume->volume > AUD_VOLUME_DB_MAX)) {
10228 return DRX_STS_INVALID_ARG;
10229 }
10230
10231 RR16(devAddr, AUD_DSP_WR_VOLUME__A, &wVolume);
10232
10233 /* clear the volume mask */
10234 wVolume &= (u16_t) ~ AUD_DSP_WR_VOLUME_VOL_MAIN__M;
10235 if (volume->mute == TRUE) {
10236 /* mute */
10237 /* mute overrules volume */
10238 wVolume |= (u16_t) (0);
10239
10240 } else {
10241 wVolume |= (u16_t) ((volume->volume + AUD_VOLUME_ZERO_DB) <<
10242 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
10243 }
10244
10245 WR16(devAddr, AUD_DSP_WR_VOLUME__A, wVolume);
10246
10247 /* automatic volume control */
10248 RR16(devAddr, AUD_DSP_WR_AVC__A, &wAVC);
10249
10250 /* clear masks that require writing */
10251 wAVC &= (u16_t) ~ AUD_DSP_WR_AVC_AVC_ON__M;
10252 wAVC &= (u16_t) ~ AUD_DSP_WR_AVC_AVC_DECAY__M;
10253
10254 if (volume->avcMode == DRX_AUD_AVC_OFF) {
10255 wAVC |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
10256 } else {
10257
10258 wAVC |= (AUD_DSP_WR_AVC_AVC_ON_ON);
10259
10260 /* avc decay */
10261 switch (volume->avcMode) {
10262 case DRX_AUD_AVC_DECAYTIME_20MS:
10263 wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
10264 break;
10265 case DRX_AUD_AVC_DECAYTIME_8S:
10266 wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
10267 break;
10268 case DRX_AUD_AVC_DECAYTIME_4S:
10269 wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
10270 break;
10271 case DRX_AUD_AVC_DECAYTIME_2S:
10272 wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
10273 break;
10274 default:
10275 return DRX_STS_INVALID_ARG;
10276 }
10277 }
10278
10279 /* max attenuation */
10280 wAVC &= (u16_t) ~ AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
10281 switch (volume->avcMaxAtten) {
10282 case DRX_AUD_AVC_MAX_ATTEN_12DB:
10283 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
10284 break;
10285 case DRX_AUD_AVC_MAX_ATTEN_18DB:
10286 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
10287 break;
10288 case DRX_AUD_AVC_MAX_ATTEN_24DB:
10289 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
10290 break;
10291 default:
10292 return DRX_STS_INVALID_ARG;
10293 }
10294
10295 /* max gain */
10296 wAVC &= (u16_t) ~ AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
10297 switch (volume->avcMaxGain) {
10298 case DRX_AUD_AVC_MAX_GAIN_0DB:
10299 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
10300 break;
10301 case DRX_AUD_AVC_MAX_GAIN_6DB:
10302 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
10303 break;
10304 case DRX_AUD_AVC_MAX_GAIN_12DB:
10305 wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
10306 break;
10307 default:
10308 return DRX_STS_INVALID_ARG;
10309 }
10310
10311 /* avc reference level */
10312 if (volume->avcRefLevel > AUD_MAX_AVC_REF_LEVEL) {
10313 return DRX_STS_INVALID_ARG;
10314 }
10315
10316 wAVC &= (u16_t) ~ AUD_DSP_WR_AVC_AVC_REF_LEV__M;
10317 wAVC |= (u16_t) (volume->avcRefLevel << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
10318
10319 WR16(devAddr, AUD_DSP_WR_AVC__A, wAVC);
10320
10321 /* all done, store config in data structure */
10322 extAttr->audData.volume = *volume;
10323
10324 return DRX_STS_OK;
10325 rw_error:
10326 return DRX_STS_ERROR;
10327 }
10328
10329 /*============================================================================*/
10330 /**
10331 * \brief Get the I2S settings
10332 * \param demod instance of demodulator
10333 * \param pointer to DRXCfgI2SOutput_t
10334 * \return DRXStatus_t.
10335 *
10336 */
10337 static DRXStatus_t
10338 AUDCtrlGetCfgOutputI2S(pDRXDemodInstance_t demod, pDRXCfgI2SOutput_t output)
10339 {
10340 pI2CDeviceAddr_t devAddr = NULL;
10341 pDRXJData_t extAttr = NULL;
10342
10343 u16_t wI2SConfig = 0;
10344 u16_t rI2SFreq = 0;
10345
10346 if (output == NULL) {
10347 return DRX_STS_INVALID_ARG;
10348 }
10349
10350 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
10351 extAttr = (pDRXJData_t) demod->myExtAttr;
10352
10353 /* power up */
10354 if (extAttr->audData.audioIsActive == FALSE) {
10355 CHK_ERROR(PowerUpAud(demod, TRUE));
10356 extAttr->audData.audioIsActive = TRUE;
10357 }
10358
10359 RR16(devAddr, AUD_DEM_RAM_I2S_CONFIG2__A, &wI2SConfig);
10360 RR16(devAddr, AUD_DSP_WR_I2S_OUT_FS__A, &rI2SFreq);
10361
10362 /* I2S mode */
10363 switch (wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
10364 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
10365 output->mode = DRX_I2S_MODE_MASTER;
10366 break;
10367 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
10368 output->mode = DRX_I2S_MODE_SLAVE;
10369 break;
10370 default:
10371 return DRX_STS_ERROR;
10372 }
10373
10374 /* I2S format */
10375 switch (wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
10376 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
10377 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
10378 break;
10379 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
10380 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
10381 break;
10382 default:
10383 return DRX_STS_ERROR;
10384 }
10385
10386 /* I2S word length */
10387 switch (wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
10388 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
10389 output->wordLength = DRX_I2S_WORDLENGTH_16;
10390 break;
10391 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
10392 output->wordLength = DRX_I2S_WORDLENGTH_32;
10393 break;
10394 default:
10395 return DRX_STS_ERROR;
10396 }
10397
10398 /* I2S polarity */
10399 switch (wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
10400 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
10401 output->polarity = DRX_I2S_POLARITY_LEFT;
10402 break;
10403 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
10404 output->polarity = DRX_I2S_POLARITY_RIGHT;
10405 break;
10406 default:
10407 return DRX_STS_ERROR;
10408 }
10409
10410 /* I2S output enabled */
10411 if ((wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M)
10412 == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE) {
10413 output->outputEnable = TRUE;
10414 } else {
10415 output->outputEnable = FALSE;
10416 }
10417
10418 if (rI2SFreq > 0) {
10419 output->frequency = 6144UL * 48000 / rI2SFreq;
10420 if (output->wordLength == DRX_I2S_WORDLENGTH_16) {
10421 output->frequency *= 2;
10422 }
10423 } else {
10424 output->frequency = AUD_I2S_FREQUENCY_MAX;
10425 }
10426
10427 return DRX_STS_OK;
10428 rw_error:
10429 return DRX_STS_ERROR;
10430 }
10431
10432 /*============================================================================*/
10433 /**
10434 * \brief Set the I2S settings
10435 * \param demod instance of demodulator
10436 * \param pointer to DRXCfgI2SOutput_t
10437 * \return DRXStatus_t.
10438 *
10439 */
10440 static DRXStatus_t
10441 AUDCtrlSetCfgOutputI2S(pDRXDemodInstance_t demod, pDRXCfgI2SOutput_t output)
10442 {
10443 pI2CDeviceAddr_t devAddr = NULL;
10444 pDRXJData_t extAttr = NULL;
10445
10446 u16_t wI2SConfig = 0;
10447 u16_t wI2SPadsDataDa = 0;
10448 u16_t wI2SPadsDataCl = 0;
10449 u16_t wI2SPadsDataWs = 0;
10450 u32_t wI2SFreq = 0;
10451
10452 if (output == NULL) {
10453 return DRX_STS_INVALID_ARG;
10454 }
10455
10456 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
10457 extAttr = (pDRXJData_t) demod->myExtAttr;
10458
10459 /* power up */
10460 if (extAttr->audData.audioIsActive == FALSE) {
10461 CHK_ERROR(PowerUpAud(demod, TRUE));
10462 extAttr->audData.audioIsActive = TRUE;
10463 }
10464
10465 RR16(devAddr, AUD_DEM_RAM_I2S_CONFIG2__A, &wI2SConfig);
10466
10467 /* I2S mode */
10468 wI2SConfig &= (u16_t) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
10469
10470 switch (output->mode) {
10471 case DRX_I2S_MODE_MASTER:
10472 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
10473 break;
10474 case DRX_I2S_MODE_SLAVE:
10475 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
10476 break;
10477 default:
10478 return DRX_STS_INVALID_ARG;
10479 }
10480
10481 /* I2S format */
10482 wI2SConfig &= (u16_t) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
10483
10484 switch (output->format) {
10485 case DRX_I2S_FORMAT_WS_ADVANCED:
10486 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
10487 break;
10488 case DRX_I2S_FORMAT_WS_WITH_DATA:
10489 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
10490 break;
10491 default:
10492 return DRX_STS_INVALID_ARG;
10493 }
10494
10495 /* I2S word length */
10496 wI2SConfig &= (u16_t) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
10497
10498 switch (output->wordLength) {
10499 case DRX_I2S_WORDLENGTH_16:
10500 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
10501 break;
10502 case DRX_I2S_WORDLENGTH_32:
10503 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
10504 break;
10505 default:
10506 return DRX_STS_INVALID_ARG;
10507 }
10508
10509 /* I2S polarity */
10510 wI2SConfig &= (u16_t) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
10511 switch (output->polarity) {
10512 case DRX_I2S_POLARITY_LEFT:
10513 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
10514 break;
10515 case DRX_I2S_POLARITY_RIGHT:
10516 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
10517 break;
10518 default:
10519 return DRX_STS_INVALID_ARG;
10520 }
10521
10522 /* I2S output enabled */
10523 wI2SConfig &= (u16_t) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
10524 if (output->outputEnable == TRUE) {
10525 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
10526 } else {
10527 wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
10528 }
10529
10530 /*
10531 I2S frequency
10532
10533 wI2SFreq = 6144 * 48000 * nrbits / ( 32 * frequency )
10534
10535 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
10536 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
10537 */
10538 if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
10539 output->frequency < AUD_I2S_FREQUENCY_MIN) {
10540 return DRX_STS_INVALID_ARG;
10541 }
10542
10543 wI2SFreq = (6144UL * 48000UL) + (output->frequency >> 1);
10544 wI2SFreq /= output->frequency;
10545
10546 if (output->wordLength == DRX_I2S_WORDLENGTH_16) {
10547 wI2SFreq *= 2;
10548 }
10549
10550 WR16(devAddr, AUD_DEM_WR_I2S_CONFIG2__A, wI2SConfig);
10551 WR16(devAddr, AUD_DSP_WR_I2S_OUT_FS__A, (u16_t) wI2SFreq);
10552
10553 /* configure I2S output pads for master or slave mode */
10554 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
10555
10556 if (output->mode == DRX_I2S_MODE_MASTER) {
10557 wI2SPadsDataDa = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
10558 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
10559 wI2SPadsDataCl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
10560 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
10561 wI2SPadsDataWs = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
10562 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
10563 } else {
10564 wI2SPadsDataDa = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
10565 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
10566 wI2SPadsDataCl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
10567 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
10568 wI2SPadsDataWs = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
10569 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
10570 }
10571
10572 WR16(devAddr, SIO_PDR_I2S_DA_CFG__A, wI2SPadsDataDa);
10573 WR16(devAddr, SIO_PDR_I2S_CL_CFG__A, wI2SPadsDataCl);
10574 WR16(devAddr, SIO_PDR_I2S_WS_CFG__A, wI2SPadsDataWs);
10575
10576 WR16(devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
10577
10578 /* all done, store config in data structure */
10579 extAttr->audData.i2sdata = *output;
10580
10581 return DRX_STS_OK;
10582 rw_error:
10583 return DRX_STS_ERROR;
10584 }
10585
10586 /*============================================================================*/
10587 /**
10588 * \brief Get the Automatic Standard Select (ASS)
10589 * and Automatic Sound Change (ASC)
10590 * \param demod instance of demodulator
10591 * \param pointer to pDRXAudAutoSound_t
10592 * \return DRXStatus_t.
10593 *
10594 */
10595 static DRXStatus_t
10596 AUDCtrlGetCfgAutoSound(pDRXDemodInstance_t demod,
10597 pDRXCfgAudAutoSound_t autoSound)
10598 {
10599 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10600 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10601
10602 u16_t rModus = 0;
10603
10604 if (autoSound == NULL) {
10605 return DRX_STS_INVALID_ARG;
10606 }
10607
10608 devAddr = demod->myI2CDevAddr;
10609 extAttr = (pDRXJData_t) demod->myExtAttr;
10610
10611 /* power up */
10612 if (extAttr->audData.audioIsActive == FALSE) {
10613 CHK_ERROR(PowerUpAud(demod, TRUE));
10614 extAttr->audData.audioIsActive = TRUE;
10615 }
10616
10617 CHK_ERROR(AUDGetModus(demod, &rModus));
10618
10619 switch (rModus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
10620 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
10621 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
10622 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
10623 *autoSound =
10624 DRX_AUD_AUTO_SOUND_OFF;
10625 break;
10626 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
10627 *autoSound =
10628 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
10629 break;
10630 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
10631 *autoSound =
10632 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
10633 break;
10634 default:
10635 return DRX_STS_ERROR;
10636 }
10637
10638 return DRX_STS_OK;
10639 rw_error:
10640 return DRX_STS_ERROR;
10641 }
10642
10643 /*============================================================================*/
10644 /**
10645 * \brief Set the Automatic Standard Select (ASS)
10646 * and Automatic Sound Change (ASC)
10647 * \param demod instance of demodulator
10648 * \param pointer to pDRXAudAutoSound_t
10649 * \return DRXStatus_t.
10650 *
10651 */
10652 static DRXStatus_t
10653 AUDCtrSetlCfgAutoSound(pDRXDemodInstance_t demod,
10654 pDRXCfgAudAutoSound_t autoSound)
10655 {
10656 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10657 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10658
10659 u16_t rModus = 0;
10660 u16_t wModus = 0;
10661
10662 if (autoSound == NULL) {
10663 return DRX_STS_INVALID_ARG;
10664 }
10665
10666 devAddr = demod->myI2CDevAddr;
10667 extAttr = (pDRXJData_t) demod->myExtAttr;
10668
10669 /* power up */
10670 if (extAttr->audData.audioIsActive == FALSE) {
10671 CHK_ERROR(PowerUpAud(demod, TRUE));
10672 extAttr->audData.audioIsActive = TRUE;
10673 }
10674
10675 CHK_ERROR(AUDGetModus(demod, &rModus));
10676
10677 wModus = rModus;
10678 /* clear ASS & ASC bits */
10679 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_ASS__M;
10680 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
10681
10682 switch (*autoSound) {
10683 case DRX_AUD_AUTO_SOUND_OFF:
10684 wModus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
10685 wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
10686 break;
10687 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
10688 wModus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
10689 wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
10690 break;
10691 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
10692 wModus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
10693 wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
10694 break;
10695 default:
10696 return DRX_STS_INVALID_ARG;
10697 }
10698
10699 if (wModus != rModus) {
10700 WR16(devAddr, AUD_DEM_WR_MODUS__A, wModus);
10701 }
10702 /* copy to data structure */
10703 extAttr->audData.autoSound = *autoSound;
10704
10705 return DRX_STS_OK;
10706 rw_error:
10707 return DRX_STS_ERROR;
10708 }
10709
10710 /*============================================================================*/
10711 /**
10712 * \brief Get the Automatic Standard Select thresholds
10713 * \param demod instance of demodulator
10714 * \param pointer to pDRXAudASSThres_t
10715 * \return DRXStatus_t.
10716 *
10717 */
10718 static DRXStatus_t
10719 AUDCtrlGetCfgASSThres(pDRXDemodInstance_t demod, pDRXCfgAudASSThres_t thres)
10720 {
10721 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10722 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10723
10724 u16_t thresA2 = 0;
10725 u16_t thresBtsc = 0;
10726 u16_t thresNicam = 0;
10727
10728 if (thres == NULL) {
10729 return DRX_STS_INVALID_ARG;
10730 }
10731
10732 devAddr = demod->myI2CDevAddr;
10733 extAttr = (pDRXJData_t) demod->myExtAttr;
10734
10735 /* power up */
10736 if (extAttr->audData.audioIsActive == FALSE) {
10737 CHK_ERROR(PowerUpAud(demod, TRUE));
10738 extAttr->audData.audioIsActive = TRUE;
10739 }
10740
10741 RR16(devAddr, AUD_DEM_RAM_A2_THRSHLD__A, &thresA2);
10742 RR16(devAddr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thresBtsc);
10743 RR16(devAddr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thresNicam);
10744
10745 thres->a2 = thresA2;
10746 thres->btsc = thresBtsc;
10747 thres->nicam = thresNicam;
10748
10749 return DRX_STS_OK;
10750 rw_error:
10751 return DRX_STS_ERROR;
10752 }
10753
10754 /*============================================================================*/
10755 /**
10756 * \brief Get the Automatic Standard Select thresholds
10757 * \param demod instance of demodulator
10758 * \param pointer to pDRXAudASSThres_t
10759 * \return DRXStatus_t.
10760 *
10761 */
10762 static DRXStatus_t
10763 AUDCtrlSetCfgASSThres(pDRXDemodInstance_t demod, pDRXCfgAudASSThres_t thres)
10764 {
10765 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10766 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10767
10768 if (thres == NULL) {
10769 return DRX_STS_INVALID_ARG;
10770 }
10771
10772 devAddr = demod->myI2CDevAddr;
10773 extAttr = (pDRXJData_t) demod->myExtAttr;
10774
10775 /* power up */
10776 if (extAttr->audData.audioIsActive == FALSE) {
10777 CHK_ERROR(PowerUpAud(demod, TRUE));
10778 extAttr->audData.audioIsActive = TRUE;
10779 }
10780
10781 WR16(devAddr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2);
10782 WR16(devAddr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc);
10783 WR16(devAddr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam);
10784
10785 /* update DRXK data structure with hardware values */
10786 extAttr->audData.assThresholds = *thres;
10787
10788 return DRX_STS_OK;
10789 rw_error:
10790 return DRX_STS_ERROR;
10791 }
10792
10793 /*============================================================================*/
10794 /**
10795 * \brief Get Audio Carrier settings
10796 * \param demod instance of demodulator
10797 * \param pointer to pDRXAudCarrier_t
10798 * \return DRXStatus_t.
10799 *
10800 */
10801 static DRXStatus_t
10802 AUDCtrlGetCfgCarrier(pDRXDemodInstance_t demod, pDRXCfgAudCarriers_t carriers)
10803 {
10804 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10805 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10806
10807 u16_t wModus = 0;
10808
10809 u16_t dcoAHi = 0;
10810 u16_t dcoALo = 0;
10811 u16_t dcoBHi = 0;
10812 u16_t dcoBLo = 0;
10813
10814 u32_t valA = 0;
10815 u32_t valB = 0;
10816
10817 u16_t dcLvlA = 0;
10818 u16_t dcLvlB = 0;
10819
10820 u16_t cmThesA = 0;
10821 u16_t cmThesB = 0;
10822
10823 if (carriers == NULL) {
10824 return DRX_STS_INVALID_ARG;
10825 }
10826
10827 devAddr = demod->myI2CDevAddr;
10828 extAttr = (pDRXJData_t) demod->myExtAttr;
10829
10830 /* power up */
10831 if (extAttr->audData.audioIsActive == FALSE) {
10832 CHK_ERROR(PowerUpAud(demod, TRUE));
10833 extAttr->audData.audioIsActive = TRUE;
10834 }
10835
10836 CHK_ERROR(AUDGetModus(demod, &wModus));
10837
10838 /* Behaviour of primary audio channel */
10839 switch (wModus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
10840 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
10841 carriers->a.opt = DRX_NO_CARRIER_MUTE;
10842 break;
10843 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
10844 carriers->a.opt = DRX_NO_CARRIER_NOISE;
10845 break;
10846 default:
10847 return DRX_STS_ERROR;
10848 break;
10849 }
10850
10851 /* Behaviour of secondary audio channel */
10852 switch (wModus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
10853 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
10854 carriers->b.opt = DRX_NO_CARRIER_MUTE;
10855 break;
10856 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
10857 carriers->b.opt = DRX_NO_CARRIER_NOISE;
10858 break;
10859 default:
10860 return DRX_STS_ERROR;
10861 break;
10862 }
10863
10864 /* frequency adjustment for primary & secondary audio channel */
10865 RR16(devAddr, AUD_DEM_RAM_DCO_A_HI__A, &dcoAHi);
10866 RR16(devAddr, AUD_DEM_RAM_DCO_A_LO__A, &dcoALo);
10867 RR16(devAddr, AUD_DEM_RAM_DCO_B_HI__A, &dcoBHi);
10868 RR16(devAddr, AUD_DEM_RAM_DCO_B_LO__A, &dcoBLo);
10869
10870 valA = (((u32_t) dcoAHi) << 12) | ((u32_t) dcoALo & 0xFFF);
10871 valB = (((u32_t) dcoBHi) << 12) | ((u32_t) dcoBLo & 0xFFF);
10872
10873 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
10874 carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
10875 carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
10876
10877 /* DC level of the incoming FM signal on the primary
10878 & seconday sound channel */
10879 RR16(devAddr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dcLvlA);
10880 RR16(devAddr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dcLvlB);
10881
10882 /* offset (kHz) = (dcLvl / 322) */
10883 carriers->a.shift = (DRX_U16TODRXFREQ(dcLvlA) / 322L);
10884 carriers->b.shift = (DRX_U16TODRXFREQ(dcLvlB) / 322L);
10885
10886 /* Carrier detetcion threshold for primary & secondary channel */
10887 RR16(devAddr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cmThesA);
10888 RR16(devAddr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cmThesB);
10889
10890 carriers->a.thres = cmThesA;
10891 carriers->b.thres = cmThesB;
10892
10893 return DRX_STS_OK;
10894 rw_error:
10895 return DRX_STS_ERROR;
10896 }
10897
10898 /*============================================================================*/
10899 /**
10900 * \brief Set Audio Carrier settings
10901 * \param demod instance of demodulator
10902 * \param pointer to pDRXAudCarrier_t
10903 * \return DRXStatus_t.
10904 *
10905 */
10906 static DRXStatus_t
10907 AUDCtrlSetCfgCarrier(pDRXDemodInstance_t demod, pDRXCfgAudCarriers_t carriers)
10908 {
10909 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
10910 pDRXJData_t extAttr = (pDRXJData_t) NULL;
10911
10912 u16_t wModus = 0;
10913 u16_t rModus = 0;
10914
10915 u16_t dcoAHi = 0;
10916 u16_t dcoALo = 0;
10917 u16_t dcoBHi = 0;
10918 u16_t dcoBLo = 0;
10919
10920 s32_t valA = 0;
10921 s32_t valB = 0;
10922
10923 if (carriers == NULL) {
10924 return DRX_STS_INVALID_ARG;
10925 }
10926
10927 devAddr = demod->myI2CDevAddr;
10928 extAttr = (pDRXJData_t) demod->myExtAttr;
10929
10930 /* power up */
10931 if (extAttr->audData.audioIsActive == FALSE) {
10932 CHK_ERROR(PowerUpAud(demod, TRUE));
10933 extAttr->audData.audioIsActive = TRUE;
10934 }
10935
10936 CHK_ERROR(AUDGetModus(demod, &rModus));
10937
10938 wModus = rModus;
10939 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_CM_A__M;
10940 /* Behaviour of primary audio channel */
10941 switch (carriers->a.opt) {
10942 case DRX_NO_CARRIER_MUTE:
10943 wModus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
10944 break;
10945 case DRX_NO_CARRIER_NOISE:
10946 wModus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
10947 break;
10948 default:
10949 return DRX_STS_INVALID_ARG;
10950 break;
10951 }
10952
10953 /* Behaviour of secondary audio channel */
10954 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_CM_B__M;
10955 switch (carriers->b.opt) {
10956 case DRX_NO_CARRIER_MUTE:
10957 wModus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
10958 break;
10959 case DRX_NO_CARRIER_NOISE:
10960 wModus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
10961 break;
10962 default:
10963 return DRX_STS_INVALID_ARG;
10964 break;
10965 }
10966
10967 /* now update the modus register */
10968 if (wModus != rModus) {
10969 WR16(devAddr, AUD_DEM_WR_MODUS__A, wModus);
10970 }
10971
10972 /* frequency adjustment for primary & secondary audio channel */
10973 valA = (s32_t) ((carriers->a.dco) * 1657L / 2);
10974 valB = (s32_t) ((carriers->b.dco) * 1657L / 2);
10975
10976 dcoAHi = (u16_t) ((valA >> 12) & 0xFFF);
10977 dcoALo = (u16_t) (valA & 0xFFF);
10978 dcoBHi = (u16_t) ((valB >> 12) & 0xFFF);
10979 dcoBLo = (u16_t) (valB & 0xFFF);
10980
10981 WR16(devAddr, AUD_DEM_WR_DCO_A_HI__A, dcoAHi);
10982 WR16(devAddr, AUD_DEM_WR_DCO_A_LO__A, dcoALo);
10983 WR16(devAddr, AUD_DEM_WR_DCO_B_HI__A, dcoBHi);
10984 WR16(devAddr, AUD_DEM_WR_DCO_B_LO__A, dcoBLo);
10985
10986 /* Carrier detetcion threshold for primary & secondary channel */
10987 WR16(devAddr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres);
10988 WR16(devAddr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres);
10989
10990 /* update DRXK data structure */
10991 extAttr->audData.carriers = *carriers;
10992
10993 return DRX_STS_OK;
10994 rw_error:
10995 return DRX_STS_ERROR;
10996 }
10997
10998 /*============================================================================*/
10999 /**
11000 * \brief Get I2S Source, I2S matrix and FM matrix
11001 * \param demod instance of demodulator
11002 * \param pointer to pDRXAudmixer_t
11003 * \return DRXStatus_t.
11004 *
11005 */
11006 static DRXStatus_t
11007 AUDCtrlGetCfgMixer(pDRXDemodInstance_t demod, pDRXCfgAudMixer_t mixer)
11008 {
11009 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11010 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11011
11012 u16_t srcI2SMatr = 0;
11013 u16_t fmMatr = 0;
11014
11015 if (mixer == NULL) {
11016 return DRX_STS_INVALID_ARG;
11017 }
11018
11019 devAddr = demod->myI2CDevAddr;
11020 extAttr = (pDRXJData_t) demod->myExtAttr;
11021
11022 /* power up */
11023 if (extAttr->audData.audioIsActive == FALSE) {
11024 CHK_ERROR(PowerUpAud(demod, TRUE));
11025 extAttr->audData.audioIsActive = TRUE;
11026 }
11027
11028 /* Source Selctor */
11029 RR16(devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, &srcI2SMatr);
11030
11031 switch (srcI2SMatr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
11032 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
11033 mixer->sourceI2S = DRX_AUD_SRC_MONO;
11034 break;
11035 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
11036 mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_AB;
11037 break;
11038 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
11039 mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_A;
11040 break;
11041 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
11042 mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_B;
11043 break;
11044 default:
11045 return DRX_STS_ERROR;
11046 }
11047
11048 /* Matrix */
11049 switch (srcI2SMatr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
11050 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
11051 mixer->matrixI2S = DRX_AUD_I2S_MATRIX_MONO;
11052 break;
11053 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
11054 mixer->matrixI2S = DRX_AUD_I2S_MATRIX_STEREO;
11055 break;
11056 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
11057 mixer->matrixI2S = DRX_AUD_I2S_MATRIX_A_MONO;
11058 break;
11059 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
11060 mixer->matrixI2S = DRX_AUD_I2S_MATRIX_B_MONO;
11061 break;
11062 default:
11063 return DRX_STS_ERROR;
11064 }
11065
11066 /* FM Matrix */
11067 RR16(devAddr, AUD_DEM_WR_FM_MATRIX__A, &fmMatr);
11068 switch (fmMatr & AUD_DEM_WR_FM_MATRIX__M) {
11069 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
11070 mixer->matrixFm = DRX_AUD_FM_MATRIX_NO_MATRIX;
11071 break;
11072 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
11073 mixer->matrixFm = DRX_AUD_FM_MATRIX_GERMAN;
11074 break;
11075 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
11076 mixer->matrixFm = DRX_AUD_FM_MATRIX_KOREAN;
11077 break;
11078 case AUD_DEM_WR_FM_MATRIX_SOUND_A:
11079 mixer->matrixFm = DRX_AUD_FM_MATRIX_SOUND_A;
11080 break;
11081 case AUD_DEM_WR_FM_MATRIX_SOUND_B:
11082 mixer->matrixFm = DRX_AUD_FM_MATRIX_SOUND_B;
11083 break;
11084 default:
11085 return DRX_STS_ERROR;
11086 }
11087
11088 return DRX_STS_OK;
11089 rw_error:
11090 return DRX_STS_ERROR;
11091 }
11092
11093 /*============================================================================*/
11094 /**
11095 * \brief Set I2S Source, I2S matrix and FM matrix
11096 * \param demod instance of demodulator
11097 * \param pointer to DRXAudmixer_t
11098 * \return DRXStatus_t.
11099 *
11100 */
11101 static DRXStatus_t
11102 AUDCtrlSetCfgMixer(pDRXDemodInstance_t demod, pDRXCfgAudMixer_t mixer)
11103 {
11104 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11105 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11106
11107 u16_t srcI2SMatr = 0;
11108 u16_t fmMatr = 0;
11109
11110 if (mixer == NULL) {
11111 return DRX_STS_INVALID_ARG;
11112 }
11113
11114 devAddr = demod->myI2CDevAddr;
11115 extAttr = (pDRXJData_t) demod->myExtAttr;
11116
11117 /* power up */
11118 if (extAttr->audData.audioIsActive == FALSE) {
11119 CHK_ERROR(PowerUpAud(demod, TRUE));
11120 extAttr->audData.audioIsActive = TRUE;
11121 }
11122
11123 /* Source Selctor */
11124 RR16(devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, &srcI2SMatr);
11125 srcI2SMatr &= (u16_t) ~ AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
11126
11127 switch (mixer->sourceI2S) {
11128 case DRX_AUD_SRC_MONO:
11129 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
11130 break;
11131 case DRX_AUD_SRC_STEREO_OR_AB:
11132 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
11133 break;
11134 case DRX_AUD_SRC_STEREO_OR_A:
11135 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
11136 break;
11137 case DRX_AUD_SRC_STEREO_OR_B:
11138 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
11139 break;
11140 default:
11141 return DRX_STS_INVALID_ARG;
11142 }
11143
11144 /* Matrix */
11145 srcI2SMatr &= (u16_t) ~ AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
11146 switch (mixer->matrixI2S) {
11147 case DRX_AUD_I2S_MATRIX_MONO:
11148 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
11149 break;
11150 case DRX_AUD_I2S_MATRIX_STEREO:
11151 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
11152 break;
11153 case DRX_AUD_I2S_MATRIX_A_MONO:
11154 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
11155 break;
11156 case DRX_AUD_I2S_MATRIX_B_MONO:
11157 srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
11158 break;
11159 default:
11160 return DRX_STS_INVALID_ARG;
11161 }
11162 /* write the result */
11163 WR16(devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, srcI2SMatr);
11164
11165 /* FM Matrix */
11166 RR16(devAddr, AUD_DEM_WR_FM_MATRIX__A, &fmMatr);
11167 fmMatr &= (u16_t) ~ AUD_DEM_WR_FM_MATRIX__M;
11168 switch (mixer->matrixFm) {
11169 case DRX_AUD_FM_MATRIX_NO_MATRIX:
11170 fmMatr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
11171 break;
11172 case DRX_AUD_FM_MATRIX_GERMAN:
11173 fmMatr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
11174 break;
11175 case DRX_AUD_FM_MATRIX_KOREAN:
11176 fmMatr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
11177 break;
11178 case DRX_AUD_FM_MATRIX_SOUND_A:
11179 fmMatr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
11180 break;
11181 case DRX_AUD_FM_MATRIX_SOUND_B:
11182 fmMatr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
11183 break;
11184 default:
11185 return DRX_STS_INVALID_ARG;
11186 }
11187
11188 /* Only write if ASS is off */
11189 if (extAttr->audData.autoSound == DRX_AUD_AUTO_SOUND_OFF) {
11190 WR16(devAddr, AUD_DEM_WR_FM_MATRIX__A, fmMatr);
11191 }
11192
11193 /* update the data structure with hardware state */
11194 extAttr->audData.mixer = *mixer;
11195
11196 return DRX_STS_OK;
11197 rw_error:
11198 return DRX_STS_ERROR;
11199 }
11200
11201 /*============================================================================*/
11202 /**
11203 * \brief Set AV Sync settings
11204 * \param demod instance of demodulator
11205 * \param pointer to DRXICfgAVSync_t
11206 * \return DRXStatus_t.
11207 *
11208 */
11209 static DRXStatus_t
11210 AUDCtrlSetCfgAVSync(pDRXDemodInstance_t demod, pDRXCfgAudAVSync_t avSync)
11211 {
11212 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11213 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11214
11215 u16_t wAudVidSync = 0;
11216
11217 if (avSync == NULL) {
11218 return DRX_STS_INVALID_ARG;
11219 }
11220
11221 devAddr = demod->myI2CDevAddr;
11222 extAttr = (pDRXJData_t) demod->myExtAttr;
11223
11224 /* power up */
11225 if (extAttr->audData.audioIsActive == FALSE) {
11226 CHK_ERROR(PowerUpAud(demod, TRUE));
11227 extAttr->audData.audioIsActive = TRUE;
11228 }
11229
11230 /* audio/video synchronisation */
11231 RR16(devAddr, AUD_DSP_WR_AV_SYNC__A, &wAudVidSync);
11232
11233 wAudVidSync &= (u16_t) ~ AUD_DSP_WR_AV_SYNC_AV_ON__M;
11234
11235 if (*avSync == DRX_AUD_AVSYNC_OFF) {
11236 wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
11237 } else {
11238 wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
11239 }
11240
11241 wAudVidSync &= (u16_t) ~ AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
11242
11243 switch (*avSync) {
11244 case DRX_AUD_AVSYNC_NTSC:
11245 wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
11246 break;
11247 case DRX_AUD_AVSYNC_MONOCHROME:
11248 wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
11249 break;
11250 case DRX_AUD_AVSYNC_PAL_SECAM:
11251 wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
11252 break;
11253 case DRX_AUD_AVSYNC_OFF:
11254 /* OK */
11255 break;
11256 default:
11257 return DRX_STS_INVALID_ARG;
11258 }
11259
11260 WR16(devAddr, AUD_DSP_WR_AV_SYNC__A, wAudVidSync);
11261 return DRX_STS_OK;
11262 rw_error:
11263 return DRX_STS_ERROR;
11264 }
11265
11266 /*============================================================================*/
11267 /**
11268 * \brief Get AV Sync settings
11269 * \param demod instance of demodulator
11270 * \param pointer to DRXICfgAVSync_t
11271 * \return DRXStatus_t.
11272 *
11273 */
11274 static DRXStatus_t
11275 AUDCtrlGetCfgAVSync(pDRXDemodInstance_t demod, pDRXCfgAudAVSync_t avSync)
11276 {
11277 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11278 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11279
11280 u16_t wAudVidSync = 0;
11281
11282 if (avSync == NULL) {
11283 return DRX_STS_INVALID_ARG;
11284 }
11285
11286 devAddr = demod->myI2CDevAddr;
11287 extAttr = (pDRXJData_t) demod->myExtAttr;
11288
11289 /* power up */
11290 if (extAttr->audData.audioIsActive == FALSE) {
11291 CHK_ERROR(PowerUpAud(demod, TRUE));
11292 extAttr->audData.audioIsActive = TRUE;
11293 }
11294
11295 /* audio/video synchronisation */
11296 RR16(devAddr, AUD_DSP_WR_AV_SYNC__A, &wAudVidSync);
11297
11298 if ((wAudVidSync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
11299 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
11300 *avSync = DRX_AUD_AVSYNC_OFF;
11301 return DRX_STS_OK;
11302 }
11303
11304 switch (wAudVidSync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
11305 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
11306 *avSync = DRX_AUD_AVSYNC_NTSC;
11307 break;
11308 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
11309 *avSync = DRX_AUD_AVSYNC_MONOCHROME;
11310 break;
11311 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
11312 *avSync = DRX_AUD_AVSYNC_PAL_SECAM;
11313 break;
11314 default:
11315 return DRX_STS_ERROR;
11316 }
11317
11318 return DRX_STS_OK;
11319 rw_error:
11320 return DRX_STS_ERROR;
11321 }
11322
11323 /*============================================================================*/
11324 /**
11325 * \brief Get deviation mode
11326 * \param demod instance of demodulator
11327 * \param pointer to DRXCfgAudDeviation_t
11328 * \return DRXStatus_t.
11329 *
11330 */
11331 static DRXStatus_t
11332 AUDCtrlGetCfgDev(pDRXDemodInstance_t demod, pDRXCfgAudDeviation_t dev)
11333 {
11334 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11335 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11336
11337 u16_t rModus = 0;
11338
11339 if (dev == NULL) {
11340 return DRX_STS_INVALID_ARG;
11341 }
11342
11343 extAttr = (pDRXJData_t) demod->myExtAttr;
11344 devAddr = demod->myI2CDevAddr;
11345
11346 CHK_ERROR(AUDGetModus(demod, &rModus));
11347
11348 switch (rModus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
11349 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
11350 *dev = DRX_AUD_DEVIATION_NORMAL;
11351 break;
11352 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
11353 *dev = DRX_AUD_DEVIATION_HIGH;
11354 break;
11355 default:
11356 return DRX_STS_ERROR;
11357 }
11358
11359 return DRX_STS_OK;
11360 rw_error:
11361 return DRX_STS_ERROR;
11362 }
11363
11364 /*============================================================================*/
11365 /**
11366 * \brief Get deviation mode
11367 * \param demod instance of demodulator
11368 * \param pointer to DRXCfgAudDeviation_t
11369 * \return DRXStatus_t.
11370 *
11371 */
11372 static DRXStatus_t
11373 AUDCtrlSetCfgDev(pDRXDemodInstance_t demod, pDRXCfgAudDeviation_t dev)
11374 {
11375 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11376 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11377
11378 u16_t wModus = 0;
11379 u16_t rModus = 0;
11380
11381 if (dev == NULL) {
11382 return DRX_STS_INVALID_ARG;
11383 }
11384
11385 extAttr = (pDRXJData_t) demod->myExtAttr;
11386 devAddr = demod->myI2CDevAddr;
11387
11388 CHK_ERROR(AUDGetModus(demod, &rModus));
11389
11390 wModus = rModus;
11391
11392 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
11393
11394 switch (*dev) {
11395 case DRX_AUD_DEVIATION_NORMAL:
11396 wModus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
11397 break;
11398 case DRX_AUD_DEVIATION_HIGH:
11399 wModus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
11400 break;
11401 default:
11402 return DRX_STS_INVALID_ARG;
11403 }
11404
11405 /* now update the modus register */
11406 if (wModus != rModus) {
11407 WR16(devAddr, AUD_DEM_WR_MODUS__A, wModus);
11408 }
11409 /* store in drxk data struct */
11410 extAttr->audData.deviation = *dev;
11411
11412 return DRX_STS_OK;
11413 rw_error:
11414 return DRX_STS_ERROR;
11415 }
11416
11417 /*============================================================================*/
11418 /**
11419 * \brief Get Prescaler settings
11420 * \param demod instance of demodulator
11421 * \param pointer to DRXCfgAudPrescale_t
11422 * \return DRXStatus_t.
11423 *
11424 */
11425 static DRXStatus_t
11426 AUDCtrlGetCfgPrescale(pDRXDemodInstance_t demod, pDRXCfgAudPrescale_t presc)
11427 {
11428 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11429 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11430
11431 u16_t rMaxFMDeviation = 0;
11432 u16_t rNicamPrescaler = 0;
11433
11434 if (presc == NULL) {
11435 return DRX_STS_INVALID_ARG;
11436 }
11437
11438 devAddr = demod->myI2CDevAddr;
11439 extAttr = (pDRXJData_t) demod->myExtAttr;
11440
11441 /* power up */
11442 if (extAttr->audData.audioIsActive == FALSE) {
11443 CHK_ERROR(PowerUpAud(demod, TRUE));
11444 extAttr->audData.audioIsActive = TRUE;
11445 }
11446
11447 /* read register data */
11448 RR16(devAddr, AUD_DSP_WR_NICAM_PRESC__A, &rNicamPrescaler);
11449 RR16(devAddr, AUD_DSP_WR_FM_PRESC__A, &rMaxFMDeviation);
11450
11451 /* calculate max FM deviation */
11452 rMaxFMDeviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
11453 if (rMaxFMDeviation > 0) {
11454 presc->fmDeviation = 3600UL + (rMaxFMDeviation >> 1);
11455 presc->fmDeviation /= rMaxFMDeviation;
11456 } else {
11457 presc->fmDeviation = 380; /* kHz */
11458 }
11459
11460 /* calculate NICAM gain from pre-scaler */
11461 /*
11462 nicamGain = 20 * ( log10( preScaler / 16) )
11463 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
11464
11465 because Log10Times100() cannot return negative numbers
11466 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
11467
11468 for 0.1dB resolution:
11469
11470 nicamGain = 200 * ( log10( preScaler / 16) )
11471 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
11472 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
11473
11474 */
11475 rNicamPrescaler >>= 8;
11476 if (rNicamPrescaler <= 1) {
11477 presc->nicamGain = -241;
11478 } else {
11479
11480 presc->nicamGain = (s16_t) (((s32_t)
11481 (Log10Times100
11482 (10 * rNicamPrescaler *
11483 rNicamPrescaler)) - (s32_t)
11484 (Log10Times100(10 * 16 * 16))));
11485 }
11486
11487 return DRX_STS_OK;
11488 rw_error:
11489 return DRX_STS_ERROR;
11490 }
11491
11492 /*============================================================================*/
11493 /**
11494 * \brief Set Prescaler settings
11495 * \param demod instance of demodulator
11496 * \param pointer to DRXCfgAudPrescale_t
11497 * \return DRXStatus_t.
11498 *
11499 */
11500 static DRXStatus_t
11501 AUDCtrlSetCfgPrescale(pDRXDemodInstance_t demod, pDRXCfgAudPrescale_t presc)
11502 {
11503 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11504 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11505
11506 u16_t wMaxFMDeviation = 0;
11507 u16_t nicamPrescaler;
11508
11509 if (presc == NULL) {
11510 return DRX_STS_INVALID_ARG;
11511 }
11512
11513 devAddr = demod->myI2CDevAddr;
11514 extAttr = (pDRXJData_t) demod->myExtAttr;
11515
11516 /* power up */
11517 if (extAttr->audData.audioIsActive == FALSE) {
11518 CHK_ERROR(PowerUpAud(demod, TRUE));
11519 extAttr->audData.audioIsActive = TRUE;
11520 }
11521
11522 /* setting of max FM deviation */
11523 wMaxFMDeviation = (u16_t) (Frac(3600UL, presc->fmDeviation, 0));
11524 wMaxFMDeviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
11525 if (wMaxFMDeviation >=
11526 AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION) {
11527 wMaxFMDeviation =
11528 AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
11529 }
11530
11531 /* NICAM Prescaler */
11532 if ((presc->nicamGain >= -241) && (presc->nicamGain <= 180)) {
11533 /* calculation
11534
11535 prescaler = 16 * 10^( GdB / 20 )
11536
11537 minval of GdB = -20*log( 16 ) = -24.1dB
11538
11539 negative numbers not allowed for dB2LinTimes100, so
11540
11541 prescaler = 16 * 10^( GdB / 20 )
11542 = 10^( (GdB / 20) + log10(16) )
11543 = 10^( (GdB + 20log10(16)) / 20 )
11544
11545 in 0.1dB
11546
11547 = 10^( G0.1dB + 200log10(16)) / 200 )
11548
11549 */
11550 nicamPrescaler = (u16_t)
11551 ((dB2LinTimes100(presc->nicamGain + 241UL) + 50UL) / 100UL);
11552
11553 /* clip result */
11554 if (nicamPrescaler > 127) {
11555 nicamPrescaler = 127;
11556 }
11557
11558 /* shift before writing to register */
11559 nicamPrescaler <<= 8;
11560 } else {
11561 return (DRX_STS_INVALID_ARG);
11562 }
11563 /* end of setting NICAM Prescaler */
11564
11565 WR16(devAddr, AUD_DSP_WR_NICAM_PRESC__A, nicamPrescaler);
11566 WR16(devAddr, AUD_DSP_WR_FM_PRESC__A, wMaxFMDeviation);
11567
11568 extAttr->audData.prescale = *presc;
11569
11570 return DRX_STS_OK;
11571 rw_error:
11572 return DRX_STS_ERROR;
11573 }
11574
11575 /*============================================================================*/
11576 /**
11577 * \brief Beep
11578 * \param demod instance of demodulator
11579 * \param pointer to DRXAudBeep_t
11580 * \return DRXStatus_t.
11581 *
11582 */
11583 static DRXStatus_t AUDCtrlBeep(pDRXDemodInstance_t demod, pDRXAudBeep_t beep)
11584 {
11585 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
11586 pDRXJData_t extAttr = (pDRXJData_t) NULL;
11587
11588 u16_t theBeep = 0;
11589 u16_t volume = 0;
11590 u32_t frequency = 0;
11591
11592 if (beep == NULL) {
11593 return DRX_STS_INVALID_ARG;
11594 }
11595
11596 devAddr = demod->myI2CDevAddr;
11597 extAttr = (pDRXJData_t) demod->myExtAttr;
11598
11599 /* power up */
11600 if (extAttr->audData.audioIsActive == FALSE) {
11601 CHK_ERROR(PowerUpAud(demod, TRUE));
11602 extAttr->audData.audioIsActive = TRUE;
11603 }
11604
11605 if ((beep->volume > 0) || (beep->volume < -127)) {
11606 return DRX_STS_INVALID_ARG;
11607 }
11608
11609 if (beep->frequency > 3000) {
11610 return DRX_STS_INVALID_ARG;
11611 }
11612
11613 volume = (u16_t) beep->volume + 127;
11614 theBeep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
11615
11616 frequency = ((u32_t) beep->frequency) * 23 / 500;
11617 if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M) {
11618 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
11619 }
11620 theBeep |= (u16_t) frequency;
11621
11622 if (beep->mute == TRUE) {
11623 theBeep = 0;
11624 }
11625
11626 WR16(devAddr, AUD_DSP_WR_BEEPER__A, theBeep);
11627
11628 return DRX_STS_OK;
11629 rw_error:
11630 return DRX_STS_ERROR;
11631 }
11632
11633 /*============================================================================*/
11634 /**
11635 * \brief Set an audio standard
11636 * \param demod instance of demodulator
11637 * \param pointer to DRXAudStandard_t
11638 * \return DRXStatus_t.
11639 *
11640 */
11641 static DRXStatus_t
11642 AUDCtrlSetStandard(pDRXDemodInstance_t demod, pDRXAudStandard_t standard)
11643 {
11644 pI2CDeviceAddr_t devAddr = NULL;
11645 pDRXJData_t extAttr = NULL;
11646 DRXStandard_t currentStandard = DRX_STANDARD_UNKNOWN;
11647
11648 u16_t wStandard = 0;
11649 u16_t wModus = 0;
11650 u16_t rModus = 0;
11651
11652 Bool_t muteBuffer = FALSE;
11653 s16_t volumeBuffer = 0;
11654 u16_t wVolume = 0;
11655
11656 if (standard == NULL) {
11657 return DRX_STS_INVALID_ARG;
11658 }
11659
11660 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
11661 extAttr = (pDRXJData_t) demod->myExtAttr;
11662
11663 /* power up */
11664 if (extAttr->audData.audioIsActive == FALSE) {
11665 CHK_ERROR(PowerUpAud(demod, FALSE));
11666 extAttr->audData.audioIsActive = TRUE;
11667 }
11668
11669 /* reset RDS data availability flag */
11670 extAttr->audData.rdsDataPresent = FALSE;
11671
11672 /* we need to mute from here to avoid noise during standard switching */
11673 muteBuffer = extAttr->audData.volume.mute;
11674 volumeBuffer = extAttr->audData.volume.volume;
11675
11676 extAttr->audData.volume.mute = TRUE;
11677 /* restore data structure from DRX ExtAttr, call volume first to mute */
11678 CHK_ERROR(AUDCtrlSetCfgVolume(demod, &extAttr->audData.volume));
11679 CHK_ERROR(AUDCtrlSetCfgCarrier(demod, &extAttr->audData.carriers));
11680 CHK_ERROR(AUDCtrlSetCfgASSThres
11681 (demod, &extAttr->audData.assThresholds));
11682 CHK_ERROR(AUDCtrSetlCfgAutoSound(demod, &extAttr->audData.autoSound));
11683 CHK_ERROR(AUDCtrlSetCfgMixer(demod, &extAttr->audData.mixer));
11684 CHK_ERROR(AUDCtrlSetCfgAVSync(demod, &extAttr->audData.avSync));
11685 CHK_ERROR(AUDCtrlSetCfgOutputI2S(demod, &extAttr->audData.i2sdata));
11686
11687 /* get prescaler from presets */
11688 CHK_ERROR(AUDCtrlSetCfgPrescale(demod, &extAttr->audData.prescale));
11689
11690 CHK_ERROR(AUDGetModus(demod, &rModus));
11691
11692 wModus = rModus;
11693
11694 switch (*standard) {
11695 case DRX_AUD_STANDARD_AUTO:
11696 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
11697 break;
11698 case DRX_AUD_STANDARD_BTSC:
11699 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
11700 if (extAttr->audData.btscDetect == DRX_BTSC_MONO_AND_SAP) {
11701 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
11702 }
11703 break;
11704 case DRX_AUD_STANDARD_A2:
11705 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
11706 break;
11707 case DRX_AUD_STANDARD_EIAJ:
11708 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
11709 break;
11710 case DRX_AUD_STANDARD_FM_STEREO:
11711 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
11712 break;
11713 case DRX_AUD_STANDARD_BG_FM:
11714 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
11715 break;
11716 case DRX_AUD_STANDARD_D_K1:
11717 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
11718 break;
11719 case DRX_AUD_STANDARD_D_K2:
11720 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
11721 break;
11722 case DRX_AUD_STANDARD_D_K3:
11723 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
11724 break;
11725 case DRX_AUD_STANDARD_BG_NICAM_FM:
11726 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
11727 break;
11728 case DRX_AUD_STANDARD_L_NICAM_AM:
11729 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
11730 break;
11731 case DRX_AUD_STANDARD_I_NICAM_FM:
11732 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
11733 break;
11734 case DRX_AUD_STANDARD_D_K_NICAM_FM:
11735 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
11736 break;
11737 case DRX_AUD_STANDARD_UNKNOWN:
11738 wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
11739 break;
11740 default:
11741 return DRX_STS_ERROR;
11742 }
11743
11744 if (*standard == DRX_AUD_STANDARD_AUTO) {
11745 /* we need the current standard here */
11746 currentStandard = extAttr->standard;
11747
11748 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
11749
11750 if ((currentStandard == DRX_STANDARD_PAL_SECAM_L) ||
11751 (currentStandard == DRX_STANDARD_PAL_SECAM_LP)) {
11752 wModus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
11753 } else {
11754 wModus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
11755 }
11756
11757 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
11758 if (currentStandard == DRX_STANDARD_NTSC) {
11759 wModus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
11760
11761 } else { /* non USA, ignore standard M to save time */
11762
11763 wModus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
11764 }
11765
11766 }
11767
11768 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
11769
11770 /* just get hardcoded deemphasis and activate here */
11771 if (extAttr->audData.deemph == DRX_AUD_FM_DEEMPH_50US) {
11772 wModus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
11773 } else {
11774 wModus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
11775 }
11776
11777 wModus &= (u16_t) ~ AUD_DEM_WR_MODUS_MOD_BTSC__M;
11778 if (extAttr->audData.btscDetect == DRX_BTSC_STEREO) {
11779 wModus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
11780 } else { /* DRX_BTSC_MONO_AND_SAP */
11781
11782 wModus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
11783 }
11784
11785 if (wModus != rModus) {
11786 WR16(devAddr, AUD_DEM_WR_MODUS__A, wModus);
11787 }
11788
11789 WR16(devAddr, AUD_DEM_WR_STANDARD_SEL__A, wStandard);
11790
11791 /**************************************************************************/
11792 /* NOT calling AUDCtrlSetCfgVolume to avoid interfering standard */
11793 /* detection, need to keep things very minimal here, but keep audio */
11794 /* buffers intact */
11795 /**************************************************************************/
11796 extAttr->audData.volume.mute = muteBuffer;
11797 if (extAttr->audData.volume.mute == FALSE) {
11798 wVolume |= (u16_t) ((volumeBuffer + AUD_VOLUME_ZERO_DB) <<
11799 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
11800 WR16(devAddr, AUD_DSP_WR_VOLUME__A, wVolume);
11801 }
11802
11803 /* write standard selected */
11804 extAttr->audData.audioStandard = *standard;
11805
11806 return DRX_STS_OK;
11807 rw_error:
11808 return DRX_STS_ERROR;
11809 }
11810
11811 /*============================================================================*/
11812 /**
11813 * \brief Get the current audio standard
11814 * \param demod instance of demodulator
11815 * \param pointer to DRXAudStandard_t
11816 * \return DRXStatus_t.
11817 *
11818 */
11819 static DRXStatus_t
11820 AUDCtrlGetStandard(pDRXDemodInstance_t demod, pDRXAudStandard_t standard)
11821 {
11822 pI2CDeviceAddr_t devAddr = NULL;
11823 pDRXJData_t extAttr = NULL;
11824
11825 u16_t rData = 0;
11826
11827 if (standard == NULL) {
11828 return DRX_STS_INVALID_ARG;
11829 }
11830
11831 extAttr = (pDRXJData_t) demod->myExtAttr;
11832 devAddr = (pI2CDeviceAddr_t) demod->myI2CDevAddr;
11833
11834 /* power up */
11835 if (extAttr->audData.audioIsActive == FALSE) {
11836 CHK_ERROR(PowerUpAud(demod, TRUE));
11837 extAttr->audData.audioIsActive = TRUE;
11838 }
11839
11840 *standard = DRX_AUD_STANDARD_UNKNOWN;
11841
11842 RR16(devAddr, AUD_DEM_RD_STANDARD_RES__A, &rData);
11843
11844 /* return OK if the detection is not ready yet */
11845 if (rData >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
11846 *standard = DRX_AUD_STANDARD_NOT_READY;
11847 return DRX_STS_OK;
11848 }
11849
11850 /* detection done, return correct standard */
11851 switch (rData) {
11852 /* no standard detected */
11853 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
11854 *standard = DRX_AUD_STANDARD_UNKNOWN;
11855 break;
11856 /* standard is KOREA(A2) */
11857 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
11858 *standard = DRX_AUD_STANDARD_A2;
11859 break;
11860 /* standard is EIA-J (Japan) */
11861 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
11862 *standard = DRX_AUD_STANDARD_EIAJ;
11863 break;
11864 /* standard is BTSC-stereo */
11865 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
11866 *standard = DRX_AUD_STANDARD_BTSC;
11867 break;
11868 /* standard is BTSC-mono (SAP) */
11869 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
11870 *standard = DRX_AUD_STANDARD_BTSC;
11871 break;
11872 /* standard is FM radio */
11873 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
11874 *standard = DRX_AUD_STANDARD_FM_STEREO;
11875 break;
11876 /* standard is BG FM */
11877 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
11878 *standard = DRX_AUD_STANDARD_BG_FM;
11879 break;
11880 /* standard is DK-1 FM */
11881 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
11882 *standard = DRX_AUD_STANDARD_D_K1;
11883 break;
11884 /* standard is DK-2 FM */
11885 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
11886 *standard = DRX_AUD_STANDARD_D_K2;
11887 break;
11888 /* standard is DK-3 FM */
11889 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
11890 *standard = DRX_AUD_STANDARD_D_K3;
11891 break;
11892 /* standard is BG-NICAM FM */
11893 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
11894 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
11895 break;
11896 /* standard is L-NICAM AM */
11897 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
11898 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
11899 break;
11900 /* standard is I-NICAM FM */
11901 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
11902 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
11903 break;
11904 /* standard is DK-NICAM FM */
11905 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
11906 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
11907 break;
11908 default:
11909 *standard = DRX_AUD_STANDARD_UNKNOWN;
11910 }
11911
11912 return DRX_STS_OK;
11913 rw_error:
11914 return DRX_STS_ERROR;
11915
11916 }
11917
11918 /*============================================================================*/
11919 /**
11920 * \brief Retreive lock status in case of FM standard
11921 * \param demod instance of demodulator
11922 * \param pointer to lock status
11923 * \return DRXStatus_t.
11924 *
11925 */
11926 static DRXStatus_t
11927 FmLockStatus(pDRXDemodInstance_t demod, pDRXLockStatus_t lockStat)
11928 {
11929 DRXAudStatus_t status;
11930
11931 /* Check detection of audio carriers */
11932 CHK_ERROR(AUDCtrlGetCarrierDetectStatus(demod, &status));
11933
11934 /* locked if either primary or secondary carrier is detected */
11935 if ((status.carrierA == TRUE) || (status.carrierB == TRUE)) {
11936 *lockStat = DRX_LOCKED;
11937 } else {
11938 *lockStat = DRX_NOT_LOCKED;
11939 }
11940
11941 return (DRX_STS_OK);
11942
11943 rw_error:
11944 return (DRX_STS_ERROR);
11945 }
11946
11947 /*============================================================================*/
11948 /**
11949 * \brief retreive signal quality in case of FM standard
11950 * \param demod instance of demodulator
11951 * \param pointer to signal quality
11952 * \return DRXStatus_t.
11953 *
11954 * Only the quality indicator field is will be supplied.
11955 * This will either be 0% or 100%, nothing in between.
11956 *
11957 */
11958 static DRXStatus_t
11959 FmSigQuality(pDRXDemodInstance_t demod, pDRXSigQuality_t sigQuality)
11960 {
11961 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
11962
11963 CHK_ERROR(FmLockStatus(demod, &lockStatus));
11964 if (lockStatus == DRX_LOCKED) {
11965 sigQuality->indicator = 100;
11966 } else {
11967 sigQuality->indicator = 0;
11968 }
11969
11970 return (DRX_STS_OK);
11971
11972 rw_error:
11973 return (DRX_STS_ERROR);
11974 }
11975
11976 #endif
11977
11978 /*===========================================================================*/
11979 /*== END AUDIO DATAPATH FUNCTIONS ==*/
11980 /*===========================================================================*/
11981
11982 /*============================================================================*/
11983 /*============================================================================*/
11984 /*== OOB DATAPATH FUNCTIONS ==*/
11985 /*============================================================================*/
11986 /*============================================================================*/
11987 #ifndef DRXJ_DIGITAL_ONLY
11988 /**
11989 * \fn DRXStatus_t GetOOBLockStatus ()
11990 * \brief Get OOB lock status.
11991 * \param devAddr I2C address
11992 \ oobLock OOB lock status.
11993 * \return DRXStatus_t.
11994 *
11995 * Gets OOB lock status
11996 *
11997 */
11998 static DRXStatus_t
11999 GetOOBLockStatus(pDRXDemodInstance_t demod,
12000 pI2CDeviceAddr_t devAddr, pDRXLockStatus_t oobLock)
12001 {
12002 DRXJSCUCmd_t scuCmd;
12003 u16_t cmdResult[2];
12004 u16_t OOBLockState;
12005
12006 *oobLock = DRX_NOT_LOCKED;
12007
12008 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
12009 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
12010 scuCmd.resultLen = 2;
12011 scuCmd.result = cmdResult;
12012 scuCmd.parameterLen = 0;
12013
12014 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12015
12016 if (scuCmd.result[1] < 0x4000) {
12017 /* 0x00 NOT LOCKED */
12018 *oobLock = DRX_NOT_LOCKED;
12019 } else if (scuCmd.result[1] < 0x8000) {
12020 /* 0x40 DEMOD LOCKED */
12021 *oobLock = DRXJ_OOB_SYNC_LOCK;
12022 } else if (scuCmd.result[1] < 0xC000) {
12023 /* 0x80 DEMOD + OOB LOCKED (system lock) */
12024 OOBLockState = scuCmd.result[1] & 0x00FF;
12025
12026 if (OOBLockState & 0x0008) {
12027 *oobLock = DRXJ_OOB_SYNC_LOCK;
12028 } else if ((OOBLockState & 0x0002) && (OOBLockState & 0x0001)) {
12029 *oobLock = DRXJ_OOB_AGC_LOCK;
12030 }
12031 } else {
12032 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
12033 *oobLock = DRX_NEVER_LOCK;
12034 }
12035
12036 /* *oobLock = scuCmd.result[1]; */
12037
12038 return (DRX_STS_OK);
12039 rw_error:
12040 return (DRX_STS_ERROR);
12041 }
12042
12043 /**
12044 * \fn DRXStatus_t GetOOBSymbolRateOffset ()
12045 * \brief Get OOB Symbol rate offset. Unit is [ppm]
12046 * \param devAddr I2C address
12047 * \ Symbol Rate Offset OOB parameter.
12048 * \return DRXStatus_t.
12049 *
12050 * Gets OOB frequency offset
12051 *
12052 */
12053 static DRXStatus_t
12054 GetOOBSymbolRateOffset(pI2CDeviceAddr_t devAddr, ps32_t SymbolRateOffset)
12055 {
12056 /* offset = -{(timingOffset/2^19)*(symbolRate/12,656250MHz)}*10^6 [ppm] */
12057 /* offset = -{(timingOffset/2^19)*(symbolRate/12656250)}*10^6 [ppm] */
12058 /* after reconfiguration: */
12059 /* offset = -{(timingOffset*symbolRate)/(2^19*12656250)}*10^6 [ppm] */
12060 /* shift symbol rate left by 5 without lossing information */
12061 /* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
12062 /* shift 10^6 left by 6 without loosing information */
12063 /* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
12064 /* trim 12656250/15625 = 810 */
12065 /* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^8*810)} [ppm] */
12066 /* offset = -[(symbolRate * 2^-5)*(timingOffset)/(2^8)]/810 [ppm] */
12067 s32_t timingOffset = 0;
12068 u32_t unsignedTimingOffset = 0;
12069 s32_t divisionFactor = 810;
12070 u16_t data = 0;
12071 u32_t symbolRate = 0;
12072 Bool_t negative = FALSE;
12073
12074 *SymbolRateOffset = 0;
12075 /* read data rate */
12076 SARR16(devAddr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data);
12077 switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
12078 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
12079 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
12080 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
12081 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
12082 symbolRate = 1024000; /* bps */
12083 break;
12084 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
12085 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
12086 symbolRate = 772000; /* bps */
12087 break;
12088 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
12089 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
12090 symbolRate = 1544000; /* bps */
12091 break;
12092 default:
12093 return (DRX_STS_ERROR);
12094 }
12095
12096 RR16(devAddr, ORX_CON_CTI_DTI_R__A, &data);
12097 /* convert data to positive and keep information about sign */
12098 if ((data & 0x8000) == 0x8000) {
12099 if (data == 0x8000)
12100 unsignedTimingOffset = 32768;
12101 else
12102 unsignedTimingOffset = 0x00007FFF & (u32_t) (-data);
12103 negative = TRUE;
12104 } else
12105 unsignedTimingOffset = (u32_t) data;
12106
12107 symbolRate = symbolRate >> 5;
12108 unsignedTimingOffset = (unsignedTimingOffset * symbolRate);
12109 unsignedTimingOffset = Frac(unsignedTimingOffset, 256, FRAC_ROUND);
12110 unsignedTimingOffset = Frac(unsignedTimingOffset,
12111 divisionFactor, FRAC_ROUND);
12112 if (negative)
12113 timingOffset = (s32_t) unsignedTimingOffset;
12114 else
12115 timingOffset = -(s32_t) unsignedTimingOffset;
12116
12117 *SymbolRateOffset = timingOffset;
12118
12119 return (DRX_STS_OK);
12120 rw_error:
12121 return (DRX_STS_ERROR);
12122 }
12123
12124 /**
12125 * \fn DRXStatus_t GetOOBFreqOffset ()
12126 * \brief Get OOB lock status.
12127 * \param devAddr I2C address
12128 * \ freqOffset OOB frequency offset.
12129 * \return DRXStatus_t.
12130 *
12131 * Gets OOB frequency offset
12132 *
12133 */
12134 static DRXStatus_t
12135 GetOOBFreqOffset(pDRXDemodInstance_t demod, pDRXFrequency_t freqOffset)
12136 {
12137 u16_t data = 0;
12138 u16_t rot = 0;
12139 u16_t symbolRateReg = 0;
12140 u32_t symbolRate = 0;
12141 s32_t coarseFreqOffset = 0;
12142 s32_t fineFreqOffset = 0;
12143 s32_t fineSign = 1;
12144 s32_t coarseSign = 1;
12145 u32_t data64Hi = 0;
12146 u32_t data64Lo = 0;
12147 u32_t tempFreqOffset = 0;
12148 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
12149 pI2CDeviceAddr_t devAddr = NULL;
12150
12151 /* check arguments */
12152 if ((demod == NULL) || (freqOffset == NULL)) {
12153 return DRX_STS_INVALID_ARG;
12154 }
12155
12156 devAddr = demod->myI2CDevAddr;
12157 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
12158
12159 *freqOffset = 0;
12160
12161 /* read sign (spectrum inversion) */
12162 RR16(devAddr, ORX_FWP_IQM_FRQ_W__A, &rot);
12163
12164 /* read frequency offset */
12165 SARR16(devAddr, SCU_RAM_ORX_FRQ_OFFSET__A, &data);
12166 /* find COARSE frequency offset */
12167 /* coarseFreqOffset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
12168 if (data & 0x8000) {
12169 data = (0xffff - data + 1);
12170 coarseSign = -1;
12171 }
12172 Mult32(data, (commonAttr->sysClockFreq * 1000) / 6, &data64Hi,
12173 &data64Lo);
12174 tempFreqOffset = (((data64Lo >> 21) & 0x7ff) | (data64Hi << 11));
12175
12176 /* get value in KHz */
12177 coarseFreqOffset = coarseSign * Frac(tempFreqOffset, 1000, FRAC_ROUND); /* KHz */
12178 /* read data rate */
12179 SARR16(devAddr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbolRateReg);
12180 switch (symbolRateReg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
12181 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
12182 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
12183 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
12184 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
12185 symbolRate = 1024000;
12186 break;
12187 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
12188 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
12189 symbolRate = 772000;
12190 break;
12191 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
12192 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
12193 symbolRate = 1544000;
12194 break;
12195 default:
12196 return (DRX_STS_ERROR);
12197 }
12198
12199 /* find FINE frequency offset */
12200 /* fineFreqOffset = ( (CORRECTION_VALUE*symbolRate) >> 18 ); */
12201 RR16(devAddr, ORX_CON_CPH_FRQ_R__A, &data);
12202 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
12203 fineFreqOffset = (symbolRate >> 5);
12204 if (data & 0x8000) {
12205 fineFreqOffset *= 0xffff - data + 1; /* Hz */
12206 fineSign = -1;
12207 } else {
12208 fineFreqOffset *= data; /* Hz */
12209 }
12210 /* Left to divide with 8192 (2^13) */
12211 fineFreqOffset = Frac(fineFreqOffset, 8192, FRAC_ROUND);
12212 /* and to divide with 1000 to get KHz */
12213 fineFreqOffset = fineSign * Frac(fineFreqOffset, 1000, FRAC_ROUND); /* KHz */
12214
12215 if ((rot & 0x8000) == 0x8000)
12216 *freqOffset = -(coarseFreqOffset + fineFreqOffset);
12217 else
12218 *freqOffset = (coarseFreqOffset + fineFreqOffset);
12219
12220 return (DRX_STS_OK);
12221 rw_error:
12222 return (DRX_STS_ERROR);
12223 }
12224
12225 /**
12226 * \fn DRXStatus_t GetOOBFrequency ()
12227 * \brief Get OOB frequency (Unit:KHz).
12228 * \param devAddr I2C address
12229 * \ frequency OOB frequency parameters.
12230 * \return DRXStatus_t.
12231 *
12232 * Gets OOB frequency
12233 *
12234 */
12235 static DRXStatus_t
12236 GetOOBFrequency(pDRXDemodInstance_t demod, pDRXFrequency_t frequency)
12237 {
12238 u16_t data = 0;
12239 DRXFrequency_t freqOffset = 0;
12240 DRXFrequency_t freq = 0;
12241 pI2CDeviceAddr_t devAddr = NULL;
12242
12243 devAddr = demod->myI2CDevAddr;
12244
12245 *frequency = 0; /* KHz */
12246
12247 SARR16(devAddr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data);
12248
12249 freq = (DRXFrequency_t) ((DRXFrequency_t) data * 50 + 50000L);
12250
12251 CHK_ERROR(GetOOBFreqOffset(demod, &freqOffset));
12252
12253 *frequency = freq + freqOffset;
12254
12255 return (DRX_STS_OK);
12256 rw_error:
12257 return (DRX_STS_ERROR);
12258 }
12259
12260 /**
12261 * \fn DRXStatus_t GetOOBMER ()
12262 * \brief Get OOB MER.
12263 * \param devAddr I2C address
12264 \ MER OOB parameter in dB.
12265 * \return DRXStatus_t.
12266 *
12267 * Gets OOB MER. Table for MER is in Programming guide.
12268 *
12269 */
12270 static DRXStatus_t GetOOBMER(pI2CDeviceAddr_t devAddr, pu32_t mer)
12271 {
12272 u16_t data = 0;
12273
12274 *mer = 0;
12275 /* READ MER */
12276 RR16(devAddr, ORX_EQU_MER_MER_R__A, &data);
12277 switch (data) {
12278 case 0: /* fall through */
12279 case 1:
12280 *mer = 39;
12281 break;
12282 case 2:
12283 *mer = 33;
12284 break;
12285 case 3:
12286 *mer = 29;
12287 break;
12288 case 4:
12289 *mer = 27;
12290 break;
12291 case 5:
12292 *mer = 25;
12293 break;
12294 case 6:
12295 *mer = 23;
12296 break;
12297 case 7:
12298 *mer = 22;
12299 break;
12300 case 8:
12301 *mer = 21;
12302 break;
12303 case 9:
12304 *mer = 20;
12305 break;
12306 case 10:
12307 *mer = 19;
12308 break;
12309 case 11:
12310 *mer = 18;
12311 break;
12312 case 12:
12313 *mer = 17;
12314 break;
12315 case 13: /* fall through */
12316 case 14:
12317 *mer = 16;
12318 break;
12319 case 15: /* fall through */
12320 case 16:
12321 *mer = 15;
12322 break;
12323 case 17: /* fall through */
12324 case 18:
12325 *mer = 14;
12326 break;
12327 case 19: /* fall through */
12328 case 20:
12329 *mer = 13;
12330 break;
12331 case 21: /* fall through */
12332 case 22:
12333 *mer = 12;
12334 break;
12335 case 23: /* fall through */
12336 case 24: /* fall through */
12337 case 25:
12338 *mer = 11;
12339 break;
12340 case 26: /* fall through */
12341 case 27: /* fall through */
12342 case 28:
12343 *mer = 10;
12344 break;
12345 case 29: /* fall through */
12346 case 30: /* fall through */
12347 case 31: /* fall through */
12348 case 32:
12349 *mer = 9;
12350 break;
12351 case 33: /* fall through */
12352 case 34: /* fall through */
12353 case 35: /* fall through */
12354 case 36:
12355 *mer = 8;
12356 break;
12357 case 37: /* fall through */
12358 case 38: /* fall through */
12359 case 39: /* fall through */
12360 case 40:
12361 *mer = 7;
12362 break;
12363 case 41: /* fall through */
12364 case 42: /* fall through */
12365 case 43: /* fall through */
12366 case 44: /* fall through */
12367 case 45:
12368 *mer = 6;
12369 break;
12370 case 46: /* fall through */
12371 case 47: /* fall through */
12372 case 48: /* fall through */
12373 case 49: /* fall through */
12374 case 50: /* fall through */
12375 *mer = 5;
12376 break;
12377 case 51: /* fall through */
12378 case 52: /* fall through */
12379 case 53: /* fall through */
12380 case 54: /* fall through */
12381 case 55: /* fall through */
12382 case 56: /* fall through */
12383 case 57:
12384 *mer = 4;
12385 break;
12386 case 58: /* fall through */
12387 case 59: /* fall through */
12388 case 60: /* fall through */
12389 case 61: /* fall through */
12390 case 62: /* fall through */
12391 case 63:
12392 *mer = 0;
12393 break;
12394 default:
12395 *mer = 0;
12396 break;
12397 }
12398 return (DRX_STS_OK);
12399 rw_error:
12400 return (DRX_STS_ERROR);
12401 }
12402 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
12403
12404 /**
12405 * \fn DRXStatus_t SetOrxNsuAox()
12406 * \brief Configure OrxNsuAox for OOB
12407 * \param demod instance of demodulator.
12408 * \param active
12409 * \return DRXStatus_t.
12410 */
12411 static DRXStatus_t SetOrxNsuAox(pDRXDemodInstance_t demod, Bool_t active)
12412 {
12413 u16_t data = 0;
12414 pI2CDeviceAddr_t devAddr = NULL;
12415 pDRXJData_t extAttr = NULL;
12416
12417 extAttr = (pDRXJData_t) demod->myExtAttr;
12418 devAddr = demod->myI2CDevAddr;
12419
12420 /* Configure NSU_AOX */
12421 RR16(devAddr, ORX_NSU_AOX_STDBY_W__A, &data);
12422 if (!active) {
12423 data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON)
12424 & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON)
12425 & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON)
12426 & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON)
12427 & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON)
12428 & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON)
12429 & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON)
12430 & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON)
12431 );
12432 } else { /* active */
12433
12434 data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON
12435 | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON
12436 | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON
12437 | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON
12438 | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON
12439 | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON
12440 | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON
12441 | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
12442 }
12443 WR16(devAddr, ORX_NSU_AOX_STDBY_W__A, data);
12444
12445 return (DRX_STS_OK);
12446 rw_error:
12447 return (DRX_STS_ERROR);
12448 }
12449
12450 /**
12451 * \fn DRXStatus_t CtrlSetOOB()
12452 * \brief Set OOB channel to be used.
12453 * \param demod instance of demodulator
12454 * \param oobParam OOB parameters for channel setting.
12455 * \frequency should be in KHz
12456 * \return DRXStatus_t.
12457 *
12458 * Accepts only. Returns error otherwise.
12459 * Demapper value is written after SCUCommand START
12460 * because START command causes COMM_EXEC transition
12461 * from 0 to 1 which causes all registers to be
12462 * overwritten with initial value
12463 *
12464 */
12465
12466 /* Nyquist filter impulse response */
12467 #define IMPULSE_COSINE_ALPHA_0_3 {-3,-4,-1, 6,10, 7,-5,-20,-25,-10,29,79,123,140} /*sqrt raised-cosine filter with alpha=0.3 */
12468 #define IMPULSE_COSINE_ALPHA_0_5 { 2, 0,-2,-2, 2, 5, 2,-10,-20,-14,20,74,125,145} /*sqrt raised-cosine filter with alpha=0.5 */
12469 #define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0,-7,-15,-16, 0,34,77,114,128} /*full raised-cosine filter with alpha=0.5 (receiver only) */
12470
12471 /* Coefficients for the nyquist fitler (total: 27 taps) */
12472 #define NYQFILTERLEN 27
12473
12474 static DRXStatus_t CtrlSetOOB(pDRXDemodInstance_t demod, pDRXOOB_t oobParam)
12475 {
12476 #ifndef DRXJ_DIGITAL_ONLY
12477 DRXOOBDownstreamStandard_t standard = DRX_OOB_MODE_A;
12478 DRXFrequency_t freq = 0; /* KHz */
12479 pI2CDeviceAddr_t devAddr = NULL;
12480 pDRXJData_t extAttr = NULL;
12481 u16_t i = 0;
12482 Bool_t mirrorFreqSpectOOB = FALSE;
12483 u16_t trkFilterValue = 0;
12484 DRXJSCUCmd_t scuCmd;
12485 u16_t setParamParameters[3];
12486 u16_t cmdResult[2] = { 0, 0 };
12487 s16_t NyquistCoeffs[4][(NYQFILTERLEN + 1) / 2] = {
12488 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
12489 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
12490 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
12491 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
12492 };
12493 u8_t mode_val[4] = { 2, 2, 0, 1 };
12494 u8_t PFICoeffs[4][6] = {
12495 {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)}, /* TARGET_MODE = 0: PFI_A = -23/32; PFI_B = -54/32; PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
12496 {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)}, /* TARGET_MODE = 1: PFI_A = -16/32; PFI_B = -40/32; PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
12497 {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}, /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
12498 {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)} /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
12499 };
12500 u16_t mode_index;
12501
12502 devAddr = demod->myI2CDevAddr;
12503 extAttr = (pDRXJData_t) demod->myExtAttr;
12504 mirrorFreqSpectOOB = extAttr->mirrorFreqSpectOOB;
12505
12506 /* Check parameters */
12507 if (oobParam == NULL) {
12508 /* power off oob module */
12509 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
12510 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
12511 scuCmd.parameterLen = 0;
12512 scuCmd.resultLen = 1;
12513 scuCmd.result = cmdResult;
12514 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12515 CHK_ERROR(SetOrxNsuAox(demod, FALSE));
12516 WR16(devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
12517
12518 extAttr->oobPowerOn = FALSE;
12519 return (DRX_STS_OK);
12520 }
12521
12522 standard = oobParam->standard;
12523
12524 freq = oobParam->frequency;
12525 if ((freq < 70000) || (freq > 130000))
12526 return (DRX_STS_ERROR);
12527 freq = (freq - 50000) / 50;
12528
12529 {
12530 u16_t index = 0;
12531 u16_t remainder = 0;
12532 pu16_t trkFiltercfg = extAttr->oobTrkFilterCfg;
12533
12534 index = (u16_t) ((freq - 400) / 200);
12535 remainder = (u16_t) ((freq - 400) % 200);
12536 trkFilterValue =
12537 trkFiltercfg[index] - (trkFiltercfg[index] -
12538 trkFiltercfg[index +
12539 1]) / 10 * remainder /
12540 20;
12541 }
12542
12543 /*********/
12544 /* Stop */
12545 /*********/
12546 WR16(devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
12547 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
12548 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
12549 scuCmd.parameterLen = 0;
12550 scuCmd.resultLen = 1;
12551 scuCmd.result = cmdResult;
12552 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12553 /*********/
12554 /* Reset */
12555 /*********/
12556 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
12557 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12558 scuCmd.parameterLen = 0;
12559 scuCmd.resultLen = 1;
12560 scuCmd.result = cmdResult;
12561 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12562 /***********/
12563 /* SET_ENV */
12564 /***********/
12565 /* set frequency, spectrum inversion and data rate */
12566 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
12567 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
12568 scuCmd.parameterLen = 3;
12569 /* 1-data rate;2-frequency */
12570 switch (oobParam->standard) {
12571 case DRX_OOB_MODE_A:
12572 if (
12573 /* signal is transmitted inverted */
12574 ((oobParam->spectrumInverted == TRUE) &
12575 /* and tuner is not mirroring the signal */
12576 (mirrorFreqSpectOOB == FALSE)) |
12577 /* or */
12578 /* signal is transmitted noninverted */
12579 ((oobParam->spectrumInverted == FALSE) &
12580 /* and tuner is mirroring the signal */
12581 (mirrorFreqSpectOOB == TRUE))
12582 )
12583 setParamParameters[0] =
12584 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
12585 else
12586 setParamParameters[0] =
12587 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
12588 break;
12589 case DRX_OOB_MODE_B_GRADE_A:
12590 if (
12591 /* signal is transmitted inverted */
12592 ((oobParam->spectrumInverted == TRUE) &
12593 /* and tuner is not mirroring the signal */
12594 (mirrorFreqSpectOOB == FALSE)) |
12595 /* or */
12596 /* signal is transmitted noninverted */
12597 ((oobParam->spectrumInverted == FALSE) &
12598 /* and tuner is mirroring the signal */
12599 (mirrorFreqSpectOOB == TRUE))
12600 )
12601 setParamParameters[0] =
12602 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
12603 else
12604 setParamParameters[0] =
12605 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
12606 break;
12607 case DRX_OOB_MODE_B_GRADE_B:
12608 default:
12609 if (
12610 /* signal is transmitted inverted */
12611 ((oobParam->spectrumInverted == TRUE) &
12612 /* and tuner is not mirroring the signal */
12613 (mirrorFreqSpectOOB == FALSE)) |
12614 /* or */
12615 /* signal is transmitted noninverted */
12616 ((oobParam->spectrumInverted == FALSE) &
12617 /* and tuner is mirroring the signal */
12618 (mirrorFreqSpectOOB == TRUE))
12619 )
12620 setParamParameters[0] =
12621 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
12622 else
12623 setParamParameters[0] =
12624 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
12625 break;
12626 }
12627 setParamParameters[1] = (u16_t) (freq & 0xFFFF);
12628 setParamParameters[2] = trkFilterValue;
12629 scuCmd.parameter = setParamParameters;
12630 scuCmd.resultLen = 1;
12631 scuCmd.result = cmdResult;
12632 mode_index = mode_val[(setParamParameters[0] & 0xC0) >> 6];
12633 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12634
12635 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0xFABA); /* Write magic word to enable pdr reg write */
12636 WR16(devAddr, SIO_PDR_OOB_CRX_CFG__A,
12637 OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B
12638 | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B);
12639 WR16(devAddr, SIO_PDR_OOB_DRX_CFG__A,
12640 OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B
12641 | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B);
12642 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0x0000); /* Write magic word to disable pdr reg write */
12643
12644 WR16(devAddr, ORX_TOP_COMM_KEY__A, 0);
12645 WR16(devAddr, ORX_FWP_AAG_LEN_W__A, 16000);
12646 WR16(devAddr, ORX_FWP_AAG_THR_W__A, 40);
12647
12648 /* ddc */
12649 WR16(devAddr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE);
12650
12651 /* nsu */
12652 WR16(devAddr, ORX_NSU_AOX_LOPOW_W__A, extAttr->oobLoPow);
12653
12654 /* initialization for target mode */
12655 WR16(devAddr, SCU_RAM_ORX_TARGET_MODE__A,
12656 SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT);
12657 WR16(devAddr, SCU_RAM_ORX_FREQ_GAIN_CORR__A,
12658 SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS);
12659
12660 /* Reset bits for timing and freq. recovery */
12661 WR16(devAddr, SCU_RAM_ORX_RST_CPH__A, 0x0001);
12662 WR16(devAddr, SCU_RAM_ORX_RST_CTI__A, 0x0002);
12663 WR16(devAddr, SCU_RAM_ORX_RST_KRN__A, 0x0004);
12664 WR16(devAddr, SCU_RAM_ORX_RST_KRP__A, 0x0008);
12665
12666 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
12667 WR16(devAddr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3);
12668 WR16(devAddr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16_t) (-2048));
12669 WR16(devAddr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8);
12670 WR16(devAddr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16_t) (-8));
12671 WR16(devAddr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1);
12672
12673 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
12674 WR16(devAddr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10);
12675 WR16(devAddr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16_t) (-2048));
12676 WR16(devAddr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8);
12677 WR16(devAddr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16_t) (-8));
12678 WR16(devAddr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1);
12679
12680 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
12681 WR16(devAddr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17);
12682 WR16(devAddr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16_t) (-2048));
12683 WR16(devAddr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8);
12684 WR16(devAddr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16_t) (-8));
12685 WR16(devAddr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2);
12686
12687 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
12688 WR16(devAddr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000);
12689 WR16(devAddr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16_t) (-2048));
12690 WR16(devAddr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8);
12691 WR16(devAddr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16_t) (-8));
12692 WR16(devAddr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3);
12693
12694 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
12695 WR16(devAddr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400);
12696 WR16(devAddr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16_t) (-2048));
12697 WR16(devAddr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8);
12698 WR16(devAddr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16_t) (-8));
12699 WR16(devAddr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4);
12700
12701 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
12702 WR16(devAddr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20);
12703 WR16(devAddr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16_t) (-2048));
12704 WR16(devAddr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4);
12705 WR16(devAddr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16_t) (-4));
12706 WR16(devAddr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5);
12707
12708 /* PRE-Filter coefficients (PFI) */
12709 WRB(devAddr, ORX_FWP_PFI_A_W__A, sizeof(PFICoeffs[mode_index]),
12710 ((pu8_t) PFICoeffs[mode_index]));
12711 WR16(devAddr, ORX_TOP_MDE_W__A, mode_index);
12712
12713 /* NYQUIST-Filter coefficients (NYQ) */
12714 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
12715 WR16(devAddr, ORX_FWP_NYQ_ADR_W__A, i);
12716 WR16(devAddr, ORX_FWP_NYQ_COF_RW__A,
12717 NyquistCoeffs[mode_index][i]);
12718 }
12719 WR16(devAddr, ORX_FWP_NYQ_ADR_W__A, 31);
12720 WR16(devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE);
12721 /*********/
12722 /* Start */
12723 /*********/
12724 scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
12725 | SCU_RAM_COMMAND_CMD_DEMOD_START;
12726 scuCmd.parameterLen = 0;
12727 scuCmd.resultLen = 1;
12728 scuCmd.result = cmdResult;
12729 CHK_ERROR(SCUCommand(devAddr, &scuCmd));
12730
12731 CHK_ERROR(SetOrxNsuAox(demod, TRUE));
12732 WR16(devAddr, ORX_NSU_AOX_STHR_W__A, extAttr->oobPreSaw);
12733
12734 extAttr->oobPowerOn = TRUE;
12735
12736 return (DRX_STS_OK);
12737 rw_error:
12738 #endif
12739 return (DRX_STS_ERROR);
12740 }
12741
12742 /**
12743 * \fn DRXStatus_t CtrlGetOOB()
12744 * \brief Set modulation standard to be used.
12745 * \param demod instance of demodulator
12746 * \param oobStatus OOB status parameters.
12747 * \return DRXStatus_t.
12748 */
12749 static DRXStatus_t
12750 CtrlGetOOB(pDRXDemodInstance_t demod, pDRXOOBStatus_t oobStatus)
12751 {
12752 #ifndef DRXJ_DIGITAL_ONLY
12753 pI2CDeviceAddr_t devAddr = NULL;
12754 pDRXJData_t extAttr = NULL;
12755 u16_t data = 0;
12756
12757 devAddr = demod->myI2CDevAddr;
12758 extAttr = (pDRXJData_t) demod->myExtAttr;
12759
12760 /* check arguments */
12761 if (oobStatus == NULL) {
12762 return (DRX_STS_INVALID_ARG);
12763 }
12764
12765 if (extAttr->oobPowerOn == FALSE)
12766 return (DRX_STS_ERROR);
12767
12768 RR16(devAddr, ORX_DDC_OFO_SET_W__A, &data);
12769 RR16(devAddr, ORX_NSU_TUN_RFGAIN_W__A, &data);
12770 RR16(devAddr, ORX_FWP_AAG_THR_W__A, &data);
12771 SARR16(devAddr, SCU_RAM_ORX_DGN_KI__A, &data);
12772 RR16(devAddr, ORX_FWP_SRC_DGN_W__A, &data);
12773
12774 CHK_ERROR(GetOOBLockStatus(demod, devAddr, &oobStatus->lock));
12775 CHK_ERROR(GetOOBFrequency(demod, &oobStatus->frequency));
12776 CHK_ERROR(GetOOBMER(devAddr, &oobStatus->mer));
12777 CHK_ERROR(GetOOBSymbolRateOffset
12778 (devAddr, &oobStatus->symbolRateOffset));
12779
12780 return (DRX_STS_OK);
12781 rw_error:
12782 #endif
12783 return (DRX_STS_ERROR);
12784 }
12785
12786 /**
12787 * \fn DRXStatus_t CtrlSetCfgOOBPreSAW()
12788 * \brief Configure PreSAW treshold value
12789 * \param cfgData Pointer to configuration parameter
12790 * \return Error code
12791 */
12792 #ifndef DRXJ_DIGITAL_ONLY
12793 static DRXStatus_t
12794 CtrlSetCfgOOBPreSAW(pDRXDemodInstance_t demod, pu16_t cfgData)
12795 {
12796 pI2CDeviceAddr_t devAddr = NULL;
12797 pDRXJData_t extAttr = NULL;
12798
12799 if (cfgData == NULL) {
12800 return (DRX_STS_INVALID_ARG);
12801 }
12802 devAddr = demod->myI2CDevAddr;
12803 extAttr = (pDRXJData_t) demod->myExtAttr;
12804
12805 WR16(devAddr, ORX_NSU_AOX_STHR_W__A, *cfgData);
12806 extAttr->oobPreSaw = *cfgData;
12807 return (DRX_STS_OK);
12808 rw_error:
12809 return (DRX_STS_ERROR);
12810 }
12811 #endif
12812
12813 /**
12814 * \fn DRXStatus_t CtrlGetCfgOOBPreSAW()
12815 * \brief Configure PreSAW treshold value
12816 * \param cfgData Pointer to configuration parameter
12817 * \return Error code
12818 */
12819 #ifndef DRXJ_DIGITAL_ONLY
12820 static DRXStatus_t
12821 CtrlGetCfgOOBPreSAW(pDRXDemodInstance_t demod, pu16_t cfgData)
12822 {
12823 pDRXJData_t extAttr = NULL;
12824
12825 if (cfgData == NULL) {
12826 return (DRX_STS_INVALID_ARG);
12827 }
12828 extAttr = (pDRXJData_t) demod->myExtAttr;
12829
12830 *cfgData = extAttr->oobPreSaw;
12831
12832 return (DRX_STS_OK);
12833 }
12834 #endif
12835
12836 /**
12837 * \fn DRXStatus_t CtrlSetCfgOOBLoPower()
12838 * \brief Configure LO Power value
12839 * \param cfgData Pointer to pDRXJCfgOobLoPower_t
12840 * \return Error code
12841 */
12842 #ifndef DRXJ_DIGITAL_ONLY
12843 static DRXStatus_t
12844 CtrlSetCfgOOBLoPower(pDRXDemodInstance_t demod, pDRXJCfgOobLoPower_t cfgData)
12845 {
12846 pI2CDeviceAddr_t devAddr = NULL;
12847 pDRXJData_t extAttr = NULL;
12848
12849 if (cfgData == NULL) {
12850 return (DRX_STS_INVALID_ARG);
12851 }
12852 devAddr = demod->myI2CDevAddr;
12853 extAttr = (pDRXJData_t) demod->myExtAttr;
12854
12855 WR16(devAddr, ORX_NSU_AOX_LOPOW_W__A, *cfgData);
12856 extAttr->oobLoPow = *cfgData;
12857 return (DRX_STS_OK);
12858 rw_error:
12859 return (DRX_STS_ERROR);
12860 }
12861 #endif
12862
12863 /**
12864 * \fn DRXStatus_t CtrlGetCfgOOBLoPower()
12865 * \brief Configure LO Power value
12866 * \param cfgData Pointer to pDRXJCfgOobLoPower_t
12867 * \return Error code
12868 */
12869 #ifndef DRXJ_DIGITAL_ONLY
12870 static DRXStatus_t
12871 CtrlGetCfgOOBLoPower(pDRXDemodInstance_t demod, pDRXJCfgOobLoPower_t cfgData)
12872 {
12873 pDRXJData_t extAttr = NULL;
12874
12875 if (cfgData == NULL) {
12876 return (DRX_STS_INVALID_ARG);
12877 }
12878 extAttr = (pDRXJData_t) demod->myExtAttr;
12879
12880 *cfgData = extAttr->oobLoPow;
12881
12882 return (DRX_STS_OK);
12883 }
12884 #endif
12885 /*============================================================================*/
12886 /*== END OOB DATAPATH FUNCTIONS ==*/
12887 /*============================================================================*/
12888
12889 /*=============================================================================
12890 ===== MC command related functions ==========================================
12891 ===========================================================================*/
12892
12893 /*=============================================================================
12894 ===== CtrlSetChannel() ==========================================================
12895 ===========================================================================*/
12896 /**
12897 * \fn DRXStatus_t CtrlSetChannel()
12898 * \brief Select a new transmission channel.
12899 * \param demod instance of demod.
12900 * \param channel Pointer to channel data.
12901 * \return DRXStatus_t.
12902 *
12903 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
12904 * must tune the tuner to the centre frequency of the NTSC/FM channel.
12905 *
12906 */
12907 static DRXStatus_t
12908 CtrlSetChannel(pDRXDemodInstance_t demod, pDRXChannel_t channel)
12909 {
12910
12911 DRXFrequency_t tunerSetFreq = 0;
12912 DRXFrequency_t tunerGetFreq = 0;
12913 DRXFrequency_t tunerFreqOffset = 0;
12914 DRXFrequency_t intermediateFreq = 0;
12915 pDRXJData_t extAttr = NULL;
12916 pI2CDeviceAddr_t devAddr = NULL;
12917 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
12918 TUNERMode_t tunerMode = 0;
12919 pDRXCommonAttr_t commonAttr = NULL;
12920 Bool_t bridgeClosed = FALSE;
12921 #ifndef DRXJ_VSB_ONLY
12922 u32_t minSymbolRate = 0;
12923 u32_t maxSymbolRate = 0;
12924 int bandwidthTemp = 0;
12925 int bandwidth = 0;
12926 #endif
12927 /*== check arguments ======================================================*/
12928 if ((demod == NULL) || (channel == NULL)) {
12929 return DRX_STS_INVALID_ARG;
12930 }
12931
12932 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
12933 devAddr = demod->myI2CDevAddr;
12934 extAttr = (pDRXJData_t) demod->myExtAttr;
12935 standard = extAttr->standard;
12936
12937 /* check valid standards */
12938 switch (standard) {
12939 case DRX_STANDARD_8VSB:
12940 #ifndef DRXJ_VSB_ONLY
12941 case DRX_STANDARD_ITU_A:
12942 case DRX_STANDARD_ITU_B:
12943 case DRX_STANDARD_ITU_C:
12944 #endif /* DRXJ_VSB_ONLY */
12945 #ifndef DRXJ_DIGITAL_ONLY
12946 case DRX_STANDARD_NTSC:
12947 case DRX_STANDARD_FM:
12948 case DRX_STANDARD_PAL_SECAM_BG:
12949 case DRX_STANDARD_PAL_SECAM_DK:
12950 case DRX_STANDARD_PAL_SECAM_I:
12951 case DRX_STANDARD_PAL_SECAM_L:
12952 case DRX_STANDARD_PAL_SECAM_LP:
12953 #endif /* DRXJ_DIGITAL_ONLY */
12954 break;
12955 case DRX_STANDARD_UNKNOWN:
12956 default:
12957 return (DRX_STS_INVALID_ARG);
12958 }
12959
12960 /* check bandwidth QAM annex B, NTSC and 8VSB */
12961 if ((standard == DRX_STANDARD_ITU_B) ||
12962 (standard == DRX_STANDARD_8VSB) ||
12963 (standard == DRX_STANDARD_NTSC)) {
12964 switch (channel->bandwidth) {
12965 case DRX_BANDWIDTH_6MHZ:
12966 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12967 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
12968 break;
12969 case DRX_BANDWIDTH_8MHZ: /* fall through */
12970 case DRX_BANDWIDTH_7MHZ: /* fall through */
12971 default:
12972 return (DRX_STS_INVALID_ARG);
12973 }
12974 }
12975 #ifndef DRXJ_DIGITAL_ONLY
12976 if (standard == DRX_STANDARD_PAL_SECAM_BG) {
12977 switch (channel->bandwidth) {
12978 case DRX_BANDWIDTH_7MHZ: /* fall through */
12979 case DRX_BANDWIDTH_8MHZ:
12980 /* ok */
12981 break;
12982 case DRX_BANDWIDTH_6MHZ: /* fall through */
12983 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12984 default:
12985 return (DRX_STS_INVALID_ARG);
12986 }
12987 }
12988 /* check bandwidth PAL/SECAM */
12989 if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
12990 (standard == DRX_STANDARD_PAL_SECAM_DK) ||
12991 (standard == DRX_STANDARD_PAL_SECAM_I) ||
12992 (standard == DRX_STANDARD_PAL_SECAM_L) ||
12993 (standard == DRX_STANDARD_PAL_SECAM_LP)) {
12994 switch (channel->bandwidth) {
12995 case DRX_BANDWIDTH_8MHZ:
12996 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12997 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
12998 break;
12999 case DRX_BANDWIDTH_6MHZ: /* fall through */
13000 case DRX_BANDWIDTH_7MHZ: /* fall through */
13001 default:
13002 return (DRX_STS_INVALID_ARG);
13003 }
13004 }
13005 #endif
13006
13007 /* For QAM annex A and annex C:
13008 -check symbolrate and constellation
13009 -derive bandwidth from symbolrate (input bandwidth is ignored)
13010 */
13011 #ifndef DRXJ_VSB_ONLY
13012 if ((standard == DRX_STANDARD_ITU_A) ||
13013 (standard == DRX_STANDARD_ITU_C)) {
13014 DRXUIOCfg_t UIOCfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
13015 int bwRolloffFactor = 0;
13016
13017 bwRolloffFactor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
13018 minSymbolRate = DRXJ_QAM_SYMBOLRATE_MIN;
13019 maxSymbolRate = DRXJ_QAM_SYMBOLRATE_MAX;
13020 /* config SMA_TX pin to SAW switch mode */
13021 CHK_ERROR(CtrlSetUIOCfg(demod, &UIOCfg));
13022
13023 if (channel->symbolrate < minSymbolRate ||
13024 channel->symbolrate > maxSymbolRate) {
13025 return (DRX_STS_INVALID_ARG);
13026 }
13027
13028 switch (channel->constellation) {
13029 case DRX_CONSTELLATION_QAM16: /* fall through */
13030 case DRX_CONSTELLATION_QAM32: /* fall through */
13031 case DRX_CONSTELLATION_QAM64: /* fall through */
13032 case DRX_CONSTELLATION_QAM128: /* fall through */
13033 case DRX_CONSTELLATION_QAM256:
13034 bandwidthTemp = channel->symbolrate * bwRolloffFactor;
13035 bandwidth = bandwidthTemp / 100;
13036
13037 if ((bandwidthTemp % 100) >= 50) {
13038 bandwidth++;
13039 }
13040
13041 if (bandwidth <= 6100000) {
13042 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13043 } else if ((bandwidth > 6100000)
13044 && (bandwidth <= 7100000)) {
13045 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
13046 } else if (bandwidth > 7100000) {
13047 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
13048 }
13049 break;
13050 default:
13051 return (DRX_STS_INVALID_ARG);
13052 }
13053 }
13054
13055 /* For QAM annex B:
13056 -check constellation
13057 */
13058 if (standard == DRX_STANDARD_ITU_B) {
13059 switch (channel->constellation) {
13060 case DRX_CONSTELLATION_AUTO:
13061 case DRX_CONSTELLATION_QAM256:
13062 case DRX_CONSTELLATION_QAM64:
13063 break;
13064 default:
13065 return (DRX_STS_INVALID_ARG);
13066 }
13067
13068 switch (channel->interleavemode) {
13069 case DRX_INTERLEAVEMODE_I128_J1:
13070 case DRX_INTERLEAVEMODE_I128_J1_V2:
13071 case DRX_INTERLEAVEMODE_I128_J2:
13072 case DRX_INTERLEAVEMODE_I64_J2:
13073 case DRX_INTERLEAVEMODE_I128_J3:
13074 case DRX_INTERLEAVEMODE_I32_J4:
13075 case DRX_INTERLEAVEMODE_I128_J4:
13076 case DRX_INTERLEAVEMODE_I16_J8:
13077 case DRX_INTERLEAVEMODE_I128_J5:
13078 case DRX_INTERLEAVEMODE_I8_J16:
13079 case DRX_INTERLEAVEMODE_I128_J6:
13080 case DRX_INTERLEAVEMODE_I128_J7:
13081 case DRX_INTERLEAVEMODE_I128_J8:
13082 case DRX_INTERLEAVEMODE_I12_J17:
13083 case DRX_INTERLEAVEMODE_I5_J4:
13084 case DRX_INTERLEAVEMODE_B52_M240:
13085 case DRX_INTERLEAVEMODE_B52_M720:
13086 case DRX_INTERLEAVEMODE_UNKNOWN:
13087 case DRX_INTERLEAVEMODE_AUTO:
13088 break;
13089 default:
13090 return (DRX_STS_INVALID_ARG);
13091 }
13092 }
13093
13094 if ((extAttr->uioSmaTxMode) == DRX_UIO_MODE_FIRMWARE_SAW) {
13095 /* SAW SW, user UIO is used for switchable SAW */
13096 DRXUIOData_t uio1 = { DRX_UIO1, FALSE };
13097
13098 switch (channel->bandwidth) {
13099 case DRX_BANDWIDTH_8MHZ:
13100 uio1.value = TRUE;
13101 break;
13102 case DRX_BANDWIDTH_7MHZ:
13103 uio1.value = FALSE;
13104 break;
13105 case DRX_BANDWIDTH_6MHZ:
13106 uio1.value = FALSE;
13107 break;
13108 case DRX_BANDWIDTH_UNKNOWN:
13109 default:
13110 return (DRX_STS_INVALID_ARG);
13111 }
13112
13113 CHK_ERROR(CtrlUIOWrite(demod, &uio1));
13114 }
13115 #endif /* DRXJ_VSB_ONLY */
13116 WR16(devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
13117 /*== Tune, fast mode ======================================================*/
13118 if (demod->myTuner != NULL) {
13119 /* Determine tuner mode and freq to tune to ... */
13120 switch (standard) {
13121 #ifndef DRXJ_DIGITAL_ONLY
13122 case DRX_STANDARD_NTSC: /* fallthrough */
13123 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13124 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13125 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13126 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13127 case DRX_STANDARD_PAL_SECAM_LP:
13128 /* expecting center frequency, not picture carrier so no
13129 conversion .... */
13130 tunerMode |= TUNER_MODE_ANALOG;
13131 tunerSetFreq = channel->frequency;
13132 break;
13133 case DRX_STANDARD_FM:
13134 /* center frequency (equals sound carrier) as input,
13135 tune to edge of SAW */
13136 tunerMode |= TUNER_MODE_ANALOG;
13137 tunerSetFreq =
13138 channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
13139 break;
13140 #endif
13141 case DRX_STANDARD_8VSB: /* fallthrough */
13142 #ifndef DRXJ_VSB_ONLY
13143 case DRX_STANDARD_ITU_A: /* fallthrough */
13144 case DRX_STANDARD_ITU_B: /* fallthrough */
13145 case DRX_STANDARD_ITU_C:
13146 #endif
13147 tunerMode |= TUNER_MODE_DIGITAL;
13148 tunerSetFreq = channel->frequency;
13149 break;
13150 case DRX_STANDARD_UNKNOWN:
13151 default:
13152 return (DRX_STS_ERROR);
13153 } /* switch(standard) */
13154
13155 tunerMode |= TUNER_MODE_SWITCH;
13156 switch (channel->bandwidth) {
13157 case DRX_BANDWIDTH_8MHZ:
13158 tunerMode |= TUNER_MODE_8MHZ;
13159 break;
13160 case DRX_BANDWIDTH_7MHZ:
13161 tunerMode |= TUNER_MODE_7MHZ;
13162 break;
13163 case DRX_BANDWIDTH_6MHZ:
13164 tunerMode |= TUNER_MODE_6MHZ;
13165 break;
13166 default:
13167 /* TODO: for FM which bandwidth to use ?
13168 also check offset from centre frequency ?
13169 For now using 6MHz.
13170 */
13171 tunerMode |= TUNER_MODE_6MHZ;
13172 break;
13173 /* return (DRX_STS_INVALID_ARG); */
13174 }
13175
13176 /* store bandwidth for GetChannel() */
13177 extAttr->currBandwidth = channel->bandwidth;
13178 extAttr->currSymbolRate = channel->symbolrate;
13179 extAttr->frequency = tunerSetFreq;
13180 if (commonAttr->tunerPortNr == 1) {
13181 /* close tuner bridge */
13182 bridgeClosed = TRUE;
13183 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
13184 /* set tuner frequency */
13185 }
13186
13187 CHK_ERROR(DRXBSP_TUNER_SetFrequency(demod->myTuner,
13188 tunerMode, tunerSetFreq));
13189 if (commonAttr->tunerPortNr == 1) {
13190 /* open tuner bridge */
13191 bridgeClosed = FALSE;
13192 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
13193 }
13194
13195 /* Get actual frequency set by tuner and compute offset */
13196 CHK_ERROR(DRXBSP_TUNER_GetFrequency(demod->myTuner,
13197 0,
13198 &tunerGetFreq,
13199 &intermediateFreq));
13200 tunerFreqOffset = tunerGetFreq - tunerSetFreq;
13201 commonAttr->intermediateFreq = intermediateFreq;
13202 } else {
13203 /* no tuner instance defined, use fixed intermediate frequency */
13204 tunerFreqOffset = 0;
13205 intermediateFreq = demod->myCommonAttr->intermediateFreq;
13206 } /* if ( demod->myTuner != NULL ) */
13207
13208 /*== Setup demod for specific standard ====================================*/
13209 switch (standard) {
13210 case DRX_STANDARD_8VSB:
13211 if (channel->mirror == DRX_MIRROR_AUTO) {
13212 extAttr->mirror = DRX_MIRROR_NO;
13213 } else {
13214 extAttr->mirror = channel->mirror;
13215 }
13216 CHK_ERROR(SetVSB(demod));
13217 CHK_ERROR(SetFrequency(demod, channel, tunerFreqOffset));
13218 break;
13219 #ifndef DRXJ_DIGITAL_ONLY
13220 case DRX_STANDARD_NTSC: /* fallthrough */
13221 case DRX_STANDARD_FM: /* fallthrough */
13222 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13223 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13224 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13225 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13226 case DRX_STANDARD_PAL_SECAM_LP:
13227 if (channel->mirror == DRX_MIRROR_AUTO) {
13228 extAttr->mirror = DRX_MIRROR_NO;
13229 } else {
13230 extAttr->mirror = channel->mirror;
13231 }
13232 CHK_ERROR(SetATVChannel(demod,
13233 tunerFreqOffset, channel, standard));
13234 break;
13235 #endif
13236 #ifndef DRXJ_VSB_ONLY
13237 case DRX_STANDARD_ITU_A: /* fallthrough */
13238 case DRX_STANDARD_ITU_B: /* fallthrough */
13239 case DRX_STANDARD_ITU_C:
13240 CHK_ERROR(SetQAMChannel(demod, channel, tunerFreqOffset));
13241 break;
13242 #endif
13243 case DRX_STANDARD_UNKNOWN:
13244 default:
13245 return (DRX_STS_ERROR);
13246 }
13247
13248 /*== Re-tune, slow mode ===================================================*/
13249 if (demod->myTuner != NULL) {
13250 /* tune to slow mode */
13251 tunerMode &= ~TUNER_MODE_SWITCH;
13252 tunerMode |= TUNER_MODE_LOCK;
13253
13254 if (commonAttr->tunerPortNr == 1) {
13255 /* close tuner bridge */
13256 bridgeClosed = TRUE;
13257 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
13258 }
13259
13260 /* set tuner frequency */
13261 CHK_ERROR(DRXBSP_TUNER_SetFrequency(demod->myTuner,
13262 tunerMode, tunerSetFreq));
13263 if (commonAttr->tunerPortNr == 1) {
13264 /* open tuner bridge */
13265 bridgeClosed = FALSE;
13266 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
13267 }
13268 }
13269
13270 /* if ( demod->myTuner !=NULL ) */
13271 /* flag the packet error counter reset */
13272 extAttr->resetPktErrAcc = TRUE;
13273
13274 return (DRX_STS_OK);
13275 rw_error:
13276 return (DRX_STS_ERROR);
13277 }
13278
13279 /*=============================================================================
13280 ===== CtrlGetChannel() ==========================================================
13281 ===========================================================================*/
13282 /**
13283 * \fn DRXStatus_t CtrlGetChannel()
13284 * \brief Retreive parameters of current transmission channel.
13285 * \param demod Pointer to demod instance.
13286 * \param channel Pointer to channel data.
13287 * \return DRXStatus_t.
13288 */
13289 static DRXStatus_t
13290 CtrlGetChannel(pDRXDemodInstance_t demod, pDRXChannel_t channel)
13291 {
13292 pI2CDeviceAddr_t devAddr = NULL;
13293 pDRXJData_t extAttr = NULL;
13294 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
13295 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
13296 pDRXCommonAttr_t commonAttr = NULL;
13297 DRXFrequency_t intermediateFreq = 0;
13298 s32_t CTLFreqOffset = 0;
13299 u32_t iqmRcRateLo = 0;
13300 u32_t adcFrequency = 0;
13301 #ifndef DRXJ_VSB_ONLY
13302 int bandwidthTemp = 0;
13303 int bandwidth = 0;
13304 #endif
13305
13306 /* check arguments */
13307 if ((demod == NULL) || (channel == NULL)) {
13308 return DRX_STS_INVALID_ARG;
13309 }
13310
13311 devAddr = demod->myI2CDevAddr;
13312 extAttr = (pDRXJData_t) demod->myExtAttr;
13313 standard = extAttr->standard;
13314 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
13315
13316 /* initialize channel fields */
13317 channel->mirror = DRX_MIRROR_UNKNOWN;
13318 channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
13319 channel->priority = DRX_PRIORITY_UNKNOWN;
13320 channel->coderate = DRX_CODERATE_UNKNOWN;
13321 channel->guard = DRX_GUARD_UNKNOWN;
13322 channel->fftmode = DRX_FFTMODE_UNKNOWN;
13323 channel->classification = DRX_CLASSIFICATION_UNKNOWN;
13324 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13325 channel->constellation = DRX_CONSTELLATION_UNKNOWN;
13326 channel->symbolrate = 0;
13327 channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
13328 channel->carrier = DRX_CARRIER_UNKNOWN;
13329 channel->framemode = DRX_FRAMEMODE_UNKNOWN;
13330 /* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
13331 channel->ldpc = DRX_LDPC_UNKNOWN;
13332
13333 if (demod->myTuner != NULL) {
13334 DRXFrequency_t tunerFreqOffset = 0;
13335 Bool_t tunerMirror = commonAttr->mirrorFreqSpect ? FALSE : TRUE;
13336
13337 /* Get frequency from tuner */
13338 CHK_ERROR(DRXBSP_TUNER_GetFrequency(demod->myTuner,
13339 0,
13340 &(channel->frequency),
13341 &intermediateFreq));
13342 tunerFreqOffset = channel->frequency - extAttr->frequency;
13343 if (tunerMirror == TRUE) {
13344 /* positive image */
13345 channel->frequency += tunerFreqOffset;
13346 } else {
13347 /* negative image */
13348 channel->frequency -= tunerFreqOffset;
13349 }
13350
13351 /* Handle sound carrier offset in RF domain */
13352 if (standard == DRX_STANDARD_FM) {
13353 channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
13354 }
13355 } else {
13356 intermediateFreq = commonAttr->intermediateFreq;
13357 }
13358
13359 /* check lock status */
13360 CHK_ERROR(CtrlLockStatus(demod, &lockStatus));
13361 if ((lockStatus == DRX_LOCKED) || (lockStatus == DRXJ_DEMOD_LOCK)) {
13362 ARR32(devAddr, IQM_RC_RATE_LO__A, &iqmRcRateLo);
13363 adcFrequency = (commonAttr->sysClockFreq * 1000) / 3;
13364
13365 channel->symbolrate =
13366 Frac28(adcFrequency, (iqmRcRateLo + (1 << 23))) >> 7;
13367
13368 switch (standard) {
13369 case DRX_STANDARD_8VSB:
13370 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13371 /* get the channel frequency */
13372 CHK_ERROR(GetCTLFreqOffset(demod, &CTLFreqOffset));
13373 channel->frequency -= CTLFreqOffset;
13374 /* get the channel constellation */
13375 channel->constellation = DRX_CONSTELLATION_AUTO;
13376 break;
13377 #ifndef DRXJ_VSB_ONLY
13378 case DRX_STANDARD_ITU_A:
13379 case DRX_STANDARD_ITU_B:
13380 case DRX_STANDARD_ITU_C:
13381 {
13382 /* get the channel frequency */
13383 CHK_ERROR(GetCTLFreqOffset
13384 (demod, &CTLFreqOffset));
13385 channel->frequency -= CTLFreqOffset;
13386
13387 if (standard == DRX_STANDARD_ITU_B) {
13388 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13389 } else {
13390 /* annex A & C */
13391
13392 u32_t rollOff = 113; /* default annex C */
13393
13394 if (standard == DRX_STANDARD_ITU_A) {
13395 rollOff = 115;
13396 }
13397
13398 bandwidthTemp =
13399 channel->symbolrate * rollOff;
13400 bandwidth = bandwidthTemp / 100;
13401
13402 if ((bandwidthTemp % 100) >= 50) {
13403 bandwidth++;
13404 }
13405
13406 if (bandwidth <= 6000000) {
13407 channel->bandwidth =
13408 DRX_BANDWIDTH_6MHZ;
13409 } else if ((bandwidth > 6000000)
13410 && (bandwidth <= 7000000)) {
13411 channel->bandwidth =
13412 DRX_BANDWIDTH_7MHZ;
13413 } else if (bandwidth > 7000000) {
13414 channel->bandwidth =
13415 DRX_BANDWIDTH_8MHZ;
13416 }
13417 } /* if (standard == DRX_STANDARD_ITU_B) */
13418
13419 {
13420 DRXJSCUCmd_t cmdSCU =
13421 { /* command */ 0,
13422 /* parameterLen */ 0,
13423 /* resultLen */ 0,
13424 /* parameter */ NULL,
13425 /* result */ NULL
13426 };
13427 u16_t cmdResult[3] = { 0, 0, 0 };
13428
13429 cmdSCU.command =
13430 SCU_RAM_COMMAND_STANDARD_QAM |
13431 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
13432 cmdSCU.parameterLen = 0;
13433 cmdSCU.resultLen = 3;
13434 cmdSCU.parameter = NULL;
13435 cmdSCU.result = cmdResult;
13436 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
13437
13438 channel->interleavemode =
13439 (DRXInterleaveModes_t) (cmdSCU.
13440 result[2]);
13441 }
13442
13443 switch (extAttr->constellation) {
13444 case DRX_CONSTELLATION_QAM256:
13445 channel->constellation =
13446 DRX_CONSTELLATION_QAM256;
13447 break;
13448 case DRX_CONSTELLATION_QAM128:
13449 channel->constellation =
13450 DRX_CONSTELLATION_QAM128;
13451 break;
13452 case DRX_CONSTELLATION_QAM64:
13453 channel->constellation =
13454 DRX_CONSTELLATION_QAM64;
13455 break;
13456 case DRX_CONSTELLATION_QAM32:
13457 channel->constellation =
13458 DRX_CONSTELLATION_QAM32;
13459 break;
13460 case DRX_CONSTELLATION_QAM16:
13461 channel->constellation =
13462 DRX_CONSTELLATION_QAM16;
13463 break;
13464 default:
13465 channel->constellation =
13466 DRX_CONSTELLATION_UNKNOWN;
13467 return (DRX_STS_ERROR);
13468 }
13469 }
13470 break;
13471 #endif
13472 #ifndef DRXJ_DIGITAL_ONLY
13473 case DRX_STANDARD_NTSC: /* fall trough */
13474 case DRX_STANDARD_PAL_SECAM_BG:
13475 case DRX_STANDARD_PAL_SECAM_DK:
13476 case DRX_STANDARD_PAL_SECAM_I:
13477 case DRX_STANDARD_PAL_SECAM_L:
13478 case DRX_STANDARD_PAL_SECAM_LP:
13479 case DRX_STANDARD_FM:
13480 CHK_ERROR(GetATVChannel(demod, channel, standard));
13481 break;
13482 #endif
13483 case DRX_STANDARD_UNKNOWN: /* fall trough */
13484 default:
13485 return (DRX_STS_ERROR);
13486 } /* switch ( standard ) */
13487
13488 if (lockStatus == DRX_LOCKED) {
13489 channel->mirror = extAttr->mirror;
13490 }
13491 }
13492 /* if ( lockStatus == DRX_LOCKED ) */
13493 return (DRX_STS_OK);
13494 rw_error:
13495 return (DRX_STS_ERROR);
13496 }
13497
13498 /*=============================================================================
13499 ===== SigQuality() ==========================================================
13500 ===========================================================================*/
13501
13502 static u16_t
13503 mer2indicator(u16_t mer, u16_t minMer, u16_t thresholdMer, u16_t maxMer)
13504 {
13505 u16_t indicator = 0;
13506
13507 if (mer < minMer) {
13508 indicator = 0;
13509 } else if (mer < thresholdMer) {
13510 if ((thresholdMer - minMer) != 0) {
13511 indicator =
13512 25 * (mer - minMer) / (thresholdMer - minMer);
13513 }
13514 } else if (mer < maxMer) {
13515 if ((maxMer - thresholdMer) != 0) {
13516 indicator =
13517 25 + 75 * (mer - thresholdMer) / (maxMer -
13518 thresholdMer);
13519 } else {
13520 indicator = 25;
13521 }
13522 } else {
13523 indicator = 100;
13524 }
13525
13526 return indicator;
13527 }
13528
13529 /**
13530 * \fn DRXStatus_t CtrlSigQuality()
13531 * \brief Retreive signal quality form device.
13532 * \param devmod Pointer to demodulator instance.
13533 * \param sigQuality Pointer to signal quality data.
13534 * \return DRXStatus_t.
13535 * \retval DRX_STS_OK sigQuality contains valid data.
13536 * \retval DRX_STS_INVALID_ARG sigQuality is NULL.
13537 * \retval DRX_STS_ERROR Erroneous data, sigQuality contains invalid data.
13538
13539 */
13540 static DRXStatus_t
13541 CtrlSigQuality(pDRXDemodInstance_t demod, pDRXSigQuality_t sigQuality)
13542 {
13543 pI2CDeviceAddr_t devAddr = NULL;
13544 pDRXJData_t extAttr = NULL;
13545 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
13546 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
13547 u16_t minMer = 0;
13548 u16_t maxMer = 0;
13549 u16_t thresholdMer = 0;
13550
13551 /* Check arguments */
13552 if ((sigQuality == NULL) || (demod == NULL)) {
13553 return (DRX_STS_INVALID_ARG);
13554 }
13555
13556 extAttr = (pDRXJData_t) demod->myExtAttr;
13557 standard = extAttr->standard;
13558
13559 /* get basic information */
13560 devAddr = demod->myI2CDevAddr;
13561 CHK_ERROR(CtrlLockStatus(demod, &lockStatus));
13562 switch (standard) {
13563 case DRX_STANDARD_8VSB:
13564 #ifdef DRXJ_SIGNAL_ACCUM_ERR
13565 CHK_ERROR(GetAccPktErr(demod, &sigQuality->packetError));
13566 #else
13567 CHK_ERROR(GetVSBPostRSPckErr
13568 (devAddr, &sigQuality->packetError));
13569 #endif
13570 if (lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED) {
13571 sigQuality->postViterbiBER = 500000;
13572 sigQuality->MER = 20;
13573 sigQuality->preViterbiBER = 0;
13574 } else {
13575 /* PostViterbi is compute in steps of 10^(-6) */
13576 CHK_ERROR(GetVSBpreViterbiBer
13577 (devAddr, &sigQuality->preViterbiBER));
13578 CHK_ERROR(GetVSBpostViterbiBer
13579 (devAddr, &sigQuality->postViterbiBER));
13580 CHK_ERROR(GetVSBMER(devAddr, &sigQuality->MER));
13581 }
13582 minMer = 20;
13583 maxMer = 360;
13584 thresholdMer = 145;
13585 sigQuality->postReedSolomonBER = 0;
13586 sigQuality->scaleFactorBER = 1000000;
13587 sigQuality->indicator =
13588 mer2indicator(sigQuality->MER, minMer, thresholdMer,
13589 maxMer);
13590 break;
13591 #ifndef DRXJ_VSB_ONLY
13592 case DRX_STANDARD_ITU_A:
13593 case DRX_STANDARD_ITU_B:
13594 case DRX_STANDARD_ITU_C:
13595 CHK_ERROR(CtrlGetQAMSigQuality(demod, sigQuality));
13596 if (lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED) {
13597 switch (extAttr->constellation) {
13598 case DRX_CONSTELLATION_QAM256:
13599 sigQuality->MER = 210;
13600 break;
13601 case DRX_CONSTELLATION_QAM128:
13602 sigQuality->MER = 180;
13603 break;
13604 case DRX_CONSTELLATION_QAM64:
13605 sigQuality->MER = 150;
13606 break;
13607 case DRX_CONSTELLATION_QAM32:
13608 sigQuality->MER = 120;
13609 break;
13610 case DRX_CONSTELLATION_QAM16:
13611 sigQuality->MER = 90;
13612 break;
13613 default:
13614 sigQuality->MER = 0;
13615 return (DRX_STS_ERROR);
13616 }
13617 }
13618
13619 switch (extAttr->constellation) {
13620 case DRX_CONSTELLATION_QAM256:
13621 minMer = 210;
13622 thresholdMer = 270;
13623 maxMer = 380;
13624 break;
13625 case DRX_CONSTELLATION_QAM64:
13626 minMer = 150;
13627 thresholdMer = 210;
13628 maxMer = 380;
13629 break;
13630 case DRX_CONSTELLATION_QAM128:
13631 case DRX_CONSTELLATION_QAM32:
13632 case DRX_CONSTELLATION_QAM16:
13633 break;
13634 default:
13635 return (DRX_STS_ERROR);
13636 }
13637 sigQuality->indicator =
13638 mer2indicator(sigQuality->MER, minMer, thresholdMer,
13639 maxMer);
13640 break;
13641 #endif
13642 #ifndef DRXJ_DIGITAL_ONLY
13643 case DRX_STANDARD_PAL_SECAM_BG:
13644 case DRX_STANDARD_PAL_SECAM_DK:
13645 case DRX_STANDARD_PAL_SECAM_I:
13646 case DRX_STANDARD_PAL_SECAM_L:
13647 case DRX_STANDARD_PAL_SECAM_LP:
13648 case DRX_STANDARD_NTSC:
13649 CHK_ERROR(AtvSigQuality(demod, sigQuality));
13650 break;
13651 case DRX_STANDARD_FM:
13652 CHK_ERROR(FmSigQuality(demod, sigQuality));
13653 break;
13654 #endif
13655 default:
13656 return (DRX_STS_ERROR);
13657 }
13658
13659 return (DRX_STS_OK);
13660 rw_error:
13661 return (DRX_STS_ERROR);
13662 }
13663
13664 /*============================================================================*/
13665
13666 /**
13667 * \fn DRXStatus_t CtrlLockStatus()
13668 * \brief Retreive lock status .
13669 * \param devAddr Pointer to demodulator device address.
13670 * \param lockStat Pointer to lock status structure.
13671 * \return DRXStatus_t.
13672 *
13673 */
13674 static DRXStatus_t
13675 CtrlLockStatus(pDRXDemodInstance_t demod, pDRXLockStatus_t lockStat)
13676 {
13677 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
13678 pDRXJData_t extAttr = NULL;
13679 pI2CDeviceAddr_t devAddr = NULL;
13680 DRXJSCUCmd_t cmdSCU = { /* command */ 0,
13681 /* parameterLen */ 0,
13682 /* resultLen */ 0,
13683 /* *parameter */ NULL,
13684 /* *result */ NULL
13685 };
13686 u16_t cmdResult[2] = { 0, 0 };
13687 u16_t demodLock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
13688
13689 /* check arguments */
13690 if ((demod == NULL) || (lockStat == NULL)) {
13691 return (DRX_STS_INVALID_ARG);
13692 }
13693
13694 devAddr = demod->myI2CDevAddr;
13695 extAttr = (pDRXJData_t) demod->myExtAttr;
13696 standard = extAttr->standard;
13697
13698 *lockStat = DRX_NOT_LOCKED;
13699
13700 /* define the SCU command code */
13701 switch (standard) {
13702 case DRX_STANDARD_8VSB:
13703 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB |
13704 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
13705 demodLock |= 0x6;
13706 break;
13707 #ifndef DRXJ_VSB_ONLY
13708 case DRX_STANDARD_ITU_A:
13709 case DRX_STANDARD_ITU_B:
13710 case DRX_STANDARD_ITU_C:
13711 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
13712 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
13713 break;
13714 #endif
13715 #ifndef DRXJ_DIGITAL_ONLY
13716 case DRX_STANDARD_NTSC:
13717 case DRX_STANDARD_PAL_SECAM_BG:
13718 case DRX_STANDARD_PAL_SECAM_DK:
13719 case DRX_STANDARD_PAL_SECAM_I:
13720 case DRX_STANDARD_PAL_SECAM_L:
13721 case DRX_STANDARD_PAL_SECAM_LP:
13722 cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
13723 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
13724 break;
13725 case DRX_STANDARD_FM:
13726 return FmLockStatus(demod, lockStat);
13727 #endif
13728 case DRX_STANDARD_UNKNOWN: /* fallthrough */
13729 default:
13730 return (DRX_STS_ERROR);
13731 }
13732
13733 /* define the SCU command paramters and execute the command */
13734 cmdSCU.parameterLen = 0;
13735 cmdSCU.resultLen = 2;
13736 cmdSCU.parameter = NULL;
13737 cmdSCU.result = cmdResult;
13738 CHK_ERROR(SCUCommand(devAddr, &cmdSCU));
13739
13740 /* set the lock status */
13741 if (cmdSCU.result[1] < demodLock) {
13742 /* 0x0000 NOT LOCKED */
13743 *lockStat = DRX_NOT_LOCKED;
13744 } else if (cmdSCU.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
13745 *lockStat = DRXJ_DEMOD_LOCK;
13746 } else if (cmdSCU.result[1] <
13747 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
13748 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
13749 *lockStat = DRX_LOCKED;
13750 } else {
13751 /* 0xC000 NEVER LOCKED */
13752 /* (system will never be able to lock to the signal) */
13753 *lockStat = DRX_NEVER_LOCK;
13754 }
13755
13756 return (DRX_STS_OK);
13757 rw_error:
13758 return (DRX_STS_ERROR);
13759 }
13760
13761 /*============================================================================*/
13762
13763 /**
13764 * \fn DRXStatus_t CtrlConstel()
13765 * \brief Retreive a constellation point via I2C.
13766 * \param demod Pointer to demodulator instance.
13767 * \param complexNr Pointer to the structure in which to store the
13768 constellation point.
13769 * \return DRXStatus_t.
13770 */
13771 static DRXStatus_t
13772 CtrlConstel(pDRXDemodInstance_t demod, pDRXComplex_t complexNr)
13773 {
13774 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
13775 /**< active standard */
13776
13777 /* check arguments */
13778 if ((demod == NULL) || (complexNr == NULL)) {
13779 return (DRX_STS_INVALID_ARG);
13780 }
13781
13782 /* read device info */
13783 standard = ((pDRXJData_t) demod->myExtAttr)->standard;
13784
13785 /* Read constellation point */
13786 switch (standard) {
13787 case DRX_STANDARD_8VSB:
13788 CHK_ERROR(CtrlGetVSBConstel(demod, complexNr));
13789 break;
13790 #ifndef DRXJ_VSB_ONLY
13791 case DRX_STANDARD_ITU_A: /* fallthrough */
13792 case DRX_STANDARD_ITU_B: /* fallthrough */
13793 case DRX_STANDARD_ITU_C:
13794 CHK_ERROR(CtrlGetQAMConstel(demod, complexNr));
13795 break;
13796 #endif
13797 case DRX_STANDARD_UNKNOWN:
13798 default:
13799 return (DRX_STS_ERROR);
13800 }
13801
13802 return (DRX_STS_OK);
13803 rw_error:
13804 return (DRX_STS_ERROR);
13805 }
13806
13807 /*============================================================================*/
13808
13809 /**
13810 * \fn DRXStatus_t CtrlSetStandard()
13811 * \brief Set modulation standard to be used.
13812 * \param standard Modulation standard.
13813 * \return DRXStatus_t.
13814 *
13815 * Setup stuff for the desired demodulation standard.
13816 * Disable and power down the previous selected demodulation standard
13817 *
13818 */
13819 static DRXStatus_t
13820 CtrlSetStandard(pDRXDemodInstance_t demod, pDRXStandard_t standard)
13821 {
13822 pDRXJData_t extAttr = NULL;
13823 DRXStandard_t prevStandard;
13824
13825 /* check arguments */
13826 if ((standard == NULL) || (demod == NULL)) {
13827 return (DRX_STS_INVALID_ARG);
13828 }
13829
13830 extAttr = (pDRXJData_t) demod->myExtAttr;
13831 prevStandard = extAttr->standard;
13832
13833 /*
13834 Stop and power down previous standard
13835 */
13836 switch (prevStandard) {
13837 #ifndef DRXJ_VSB_ONLY
13838 case DRX_STANDARD_ITU_A: /* fallthrough */
13839 case DRX_STANDARD_ITU_B: /* fallthrough */
13840 case DRX_STANDARD_ITU_C:
13841 CHK_ERROR(PowerDownQAM(demod, FALSE));
13842 break;
13843 #endif
13844 case DRX_STANDARD_8VSB:
13845 CHK_ERROR(PowerDownVSB(demod, FALSE));
13846 break;
13847 #ifndef DRXJ_DIGITAL_ONLY
13848 case DRX_STANDARD_NTSC: /* fallthrough */
13849 case DRX_STANDARD_FM: /* fallthrough */
13850 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13851 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13852 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13853 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13854 case DRX_STANDARD_PAL_SECAM_LP:
13855 CHK_ERROR(PowerDownATV(demod, prevStandard, FALSE));
13856 break;
13857 #endif
13858 case DRX_STANDARD_UNKNOWN:
13859 /* Do nothing */
13860 break;
13861 case DRX_STANDARD_AUTO: /* fallthrough */
13862 default:
13863 return (DRX_STS_INVALID_ARG);
13864 }
13865
13866 /*
13867 Initialize channel independent registers
13868 Power up new standard
13869 */
13870 extAttr->standard = *standard;
13871
13872 switch (*standard) {
13873 #ifndef DRXJ_VSB_ONLY
13874 case DRX_STANDARD_ITU_A: /* fallthrough */
13875 case DRX_STANDARD_ITU_B: /* fallthrough */
13876 case DRX_STANDARD_ITU_C:
13877 DUMMY_READ();
13878 break;
13879 #endif
13880 case DRX_STANDARD_8VSB:
13881 CHK_ERROR(SetVSBLeakNGain(demod));
13882 break;
13883 #ifndef DRXJ_DIGITAL_ONLY
13884 case DRX_STANDARD_NTSC: /* fallthrough */
13885 case DRX_STANDARD_FM: /* fallthrough */
13886 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13887 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13888 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13889 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13890 case DRX_STANDARD_PAL_SECAM_LP:
13891 CHK_ERROR(SetATVStandard(demod, standard));
13892 CHK_ERROR(PowerUpATV(demod, *standard));
13893 break;
13894 #endif
13895 default:
13896 extAttr->standard = DRX_STANDARD_UNKNOWN;
13897 return (DRX_STS_INVALID_ARG);
13898 break;
13899 }
13900
13901 return (DRX_STS_OK);
13902 rw_error:
13903 /* Don't know what the standard is now ... try again */
13904 extAttr->standard = DRX_STANDARD_UNKNOWN;
13905 return (DRX_STS_ERROR);
13906 }
13907
13908 /*============================================================================*/
13909
13910 /**
13911 * \fn DRXStatus_t CtrlGetStandard()
13912 * \brief Get modulation standard currently used to demodulate.
13913 * \param standard Modulation standard.
13914 * \return DRXStatus_t.
13915 *
13916 * Returns 8VSB, NTSC, QAM only.
13917 *
13918 */
13919 static DRXStatus_t
13920 CtrlGetStandard(pDRXDemodInstance_t demod, pDRXStandard_t standard)
13921 {
13922 pDRXJData_t extAttr = NULL;
13923 extAttr = (pDRXJData_t) demod->myExtAttr;
13924
13925 /* check arguments */
13926 if (standard == NULL) {
13927 return (DRX_STS_INVALID_ARG);
13928 }
13929 (*standard) = extAttr->standard;
13930 DUMMY_READ();
13931
13932 return (DRX_STS_OK);
13933 rw_error:
13934 return (DRX_STS_ERROR);
13935 }
13936
13937 /*============================================================================*/
13938
13939 /**
13940 * \fn DRXStatus_t CtrlGetCfgSymbolClockOffset()
13941 * \brief Get frequency offsets of STR.
13942 * \param pointer to s32_t.
13943 * \return DRXStatus_t.
13944 *
13945 */
13946 static DRXStatus_t
13947 CtrlGetCfgSymbolClockOffset(pDRXDemodInstance_t demod, ps32_t rateOffset)
13948 {
13949 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
13950 pI2CDeviceAddr_t devAddr = NULL;
13951 pDRXJData_t extAttr = NULL;
13952
13953 /* check arguments */
13954 if (rateOffset == NULL) {
13955 return (DRX_STS_INVALID_ARG);
13956 }
13957
13958 devAddr = demod->myI2CDevAddr;
13959 extAttr = (pDRXJData_t) demod->myExtAttr;
13960 standard = extAttr->standard;
13961
13962 switch (standard) {
13963 case DRX_STANDARD_8VSB: /* fallthrough */
13964 #ifndef DRXJ_VSB_ONLY
13965 case DRX_STANDARD_ITU_A: /* fallthrough */
13966 case DRX_STANDARD_ITU_B: /* fallthrough */
13967 case DRX_STANDARD_ITU_C:
13968 #endif
13969 CHK_ERROR(GetSTRFreqOffset(demod, rateOffset));
13970 break;
13971 case DRX_STANDARD_NTSC:
13972 case DRX_STANDARD_UNKNOWN:
13973 default:
13974 return (DRX_STS_INVALID_ARG);
13975 }
13976
13977 return (DRX_STS_OK);
13978 rw_error:
13979 return (DRX_STS_ERROR);
13980 }
13981
13982 /*============================================================================*/
13983
13984 /**
13985 * \fn DRXStatus_t CtrlPowerMode()
13986 * \brief Set the power mode of the device to the specified power mode
13987 * \param demod Pointer to demodulator instance.
13988 * \param mode Pointer to new power mode.
13989 * \return DRXStatus_t.
13990 * \retval DRX_STS_OK Success
13991 * \retval DRX_STS_ERROR I2C error or other failure
13992 * \retval DRX_STS_INVALID_ARG Invalid mode argument.
13993 *
13994 *
13995 */
13996 static DRXStatus_t
13997 CtrlPowerMode(pDRXDemodInstance_t demod, pDRXPowerMode_t mode)
13998 {
13999 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) NULL;
14000 pDRXJData_t extAttr = (pDRXJData_t) NULL;
14001 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
14002 u16_t sioCcPwdMode = 0;
14003
14004 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
14005 extAttr = (pDRXJData_t) demod->myExtAttr;
14006 devAddr = demod->myI2CDevAddr;
14007
14008 /* Check arguments */
14009 if (mode == NULL) {
14010 return (DRX_STS_INVALID_ARG);
14011 }
14012
14013 /* If already in requested power mode, do nothing */
14014 if (commonAttr->currentPowerMode == *mode) {
14015 return (DRX_STS_OK);
14016 }
14017
14018 switch (*mode) {
14019 case DRX_POWER_UP:
14020 case DRXJ_POWER_DOWN_MAIN_PATH:
14021 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
14022 break;
14023 case DRXJ_POWER_DOWN_CORE:
14024 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
14025 break;
14026 case DRXJ_POWER_DOWN_PLL:
14027 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
14028 break;
14029 case DRX_POWER_DOWN:
14030 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
14031 break;
14032 default:
14033 /* Unknow sleep mode */
14034 return (DRX_STS_INVALID_ARG);
14035 break;
14036 }
14037
14038 /* Check if device needs to be powered up */
14039 if ((commonAttr->currentPowerMode != DRX_POWER_UP)) {
14040 CHK_ERROR(PowerUpDevice(demod));
14041 }
14042
14043 if ((*mode == DRX_POWER_UP)) {
14044 /* Restore analog & pin configuartion */
14045 } else {
14046 /* Power down to requested mode */
14047 /* Backup some register settings */
14048 /* Set pins with possible pull-ups connected to them in input mode */
14049 /* Analog power down */
14050 /* ADC power down */
14051 /* Power down device */
14052 /* stop all comm_exec */
14053 /*
14054 Stop and power down previous standard
14055 */
14056
14057 switch (extAttr->standard) {
14058 case DRX_STANDARD_ITU_A:
14059 case DRX_STANDARD_ITU_B:
14060 case DRX_STANDARD_ITU_C:
14061 CHK_ERROR(PowerDownQAM(demod, TRUE));
14062 break;
14063 case DRX_STANDARD_8VSB:
14064 CHK_ERROR(PowerDownVSB(demod, TRUE));
14065 break;
14066 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14067 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14068 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14069 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14070 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14071 case DRX_STANDARD_NTSC: /* fallthrough */
14072 case DRX_STANDARD_FM:
14073 CHK_ERROR(PowerDownATV(demod, extAttr->standard, TRUE));
14074 break;
14075 case DRX_STANDARD_UNKNOWN:
14076 /* Do nothing */
14077 break;
14078 case DRX_STANDARD_AUTO: /* fallthrough */
14079 default:
14080 return (DRX_STS_ERROR);
14081 }
14082
14083 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
14084 WR16(devAddr, SIO_CC_PWD_MODE__A, sioCcPwdMode);
14085 WR16(devAddr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
14086
14087 /* Initialize HI, wakeup key especially before put IC to sleep */
14088 CHK_ERROR(InitHI(demod));
14089
14090 extAttr->HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
14091 CHK_ERROR(HICfgCommand(demod));
14092 }
14093 }
14094
14095 commonAttr->currentPowerMode = *mode;
14096
14097 return (DRX_STS_OK);
14098 rw_error:
14099 return (DRX_STS_ERROR);
14100 }
14101
14102 /*============================================================================*/
14103
14104 /**
14105 * \fn DRXStatus_t CtrlVersion()
14106 * \brief Report version of microcode and if possible version of device
14107 * \param demod Pointer to demodulator instance.
14108 * \param versionList Pointer to pointer of linked list of versions.
14109 * \return DRXStatus_t.
14110 *
14111 * Using static structures so no allocation of memory is needed.
14112 * Filling in all the fields each time, cause you don't know if they are
14113 * changed by the application.
14114 *
14115 * For device:
14116 * Major version number will be last two digits of family number.
14117 * Minor number will be full respin number
14118 * Patch will be metal fix number+1
14119 * Examples:
14120 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
14121 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
14122 *
14123 */
14124 static DRXStatus_t
14125 CtrlVersion(pDRXDemodInstance_t demod, pDRXVersionList_t * versionList)
14126 {
14127 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
14128 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
14129 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
14130 u16_t ucodeMajorMinor = 0; /* BCD Ma:Ma:Ma:Mi */
14131 u16_t ucodePatch = 0; /* BCD Pa:Pa:Pa:Pa */
14132 u16_t major = 0;
14133 u16_t minor = 0;
14134 u16_t patch = 0;
14135 u16_t idx = 0;
14136 u32_t jtag = 0;
14137 u16_t subtype = 0;
14138 u16_t mfx = 0;
14139 u16_t bid = 0;
14140 u16_t key = 0;
14141
14142 static char ucodeName[] = "Microcode";
14143 static char deviceName[] = "Device";
14144
14145 devAddr = demod->myI2CDevAddr;
14146 extAttr = (pDRXJData_t) demod->myExtAttr;
14147 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
14148
14149 /* Microcode version *************************************** */
14150
14151 extAttr->vVersion[0].moduleType = DRX_MODULE_MICROCODE;
14152 extAttr->vVersion[0].moduleName = ucodeName;
14153 extAttr->vVersion[0].vString = extAttr->vText[0];
14154
14155 if (commonAttr->isOpened == TRUE) {
14156 SARR16(devAddr, SCU_RAM_VERSION_HI__A, &ucodeMajorMinor);
14157 SARR16(devAddr, SCU_RAM_VERSION_LO__A, &ucodePatch);
14158
14159 /* Translate BCD to numbers and string */
14160 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
14161 minor = (ucodeMajorMinor & 0xF);
14162 ucodeMajorMinor >>= 4;
14163 major = (ucodeMajorMinor & 0xF);
14164 ucodeMajorMinor >>= 4;
14165 major += (10 * (ucodeMajorMinor & 0xF));
14166 patch = (ucodePatch & 0xF);
14167 ucodePatch >>= 4;
14168 patch += (10 * (ucodePatch & 0xF));
14169 ucodePatch >>= 4;
14170 patch += (100 * (ucodePatch & 0xF));
14171 } else {
14172 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
14173 patch = 0;
14174 minor = 0;
14175 major = 0;
14176 }
14177 extAttr->vVersion[0].vMajor = major;
14178 extAttr->vVersion[0].vMinor = minor;
14179 extAttr->vVersion[0].vPatch = patch;
14180
14181 if (major / 10 != 0) {
14182 extAttr->vVersion[0].vString[idx++] =
14183 ((char)(major / 10)) + '0';
14184 major %= 10;
14185 }
14186 extAttr->vVersion[0].vString[idx++] = ((char)major) + '0';
14187 extAttr->vVersion[0].vString[idx++] = '.';
14188 extAttr->vVersion[0].vString[idx++] = ((char)minor) + '0';
14189 extAttr->vVersion[0].vString[idx++] = '.';
14190 if (patch / 100 != 0) {
14191 extAttr->vVersion[0].vString[idx++] =
14192 ((char)(patch / 100)) + '0';
14193 patch %= 100;
14194 }
14195 if (patch / 10 != 0) {
14196 extAttr->vVersion[0].vString[idx++] =
14197 ((char)(patch / 10)) + '0';
14198 patch %= 10;
14199 }
14200 extAttr->vVersion[0].vString[idx++] = ((char)patch) + '0';
14201 extAttr->vVersion[0].vString[idx] = '\0';
14202
14203 extAttr->vListElements[0].version = &(extAttr->vVersion[0]);
14204 extAttr->vListElements[0].next = &(extAttr->vListElements[1]);
14205
14206 /* Device version *************************************** */
14207 /* Check device id */
14208 RR16(devAddr, SIO_TOP_COMM_KEY__A, &key);
14209 WR16(devAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
14210 RR32(devAddr, SIO_TOP_JTAGID_LO__A, &jtag);
14211 RR16(devAddr, SIO_PDR_UIO_IN_HI__A, &bid);
14212 WR16(devAddr, SIO_TOP_COMM_KEY__A, key);
14213
14214 extAttr->vVersion[1].moduleType = DRX_MODULE_DEVICE;
14215 extAttr->vVersion[1].moduleName = deviceName;
14216 extAttr->vVersion[1].vString = extAttr->vText[1];
14217 extAttr->vVersion[1].vString[0] = 'D';
14218 extAttr->vVersion[1].vString[1] = 'R';
14219 extAttr->vVersion[1].vString[2] = 'X';
14220 extAttr->vVersion[1].vString[3] = '3';
14221 extAttr->vVersion[1].vString[4] = '9';
14222 extAttr->vVersion[1].vString[7] = 'J';
14223 extAttr->vVersion[1].vString[8] = ':';
14224 extAttr->vVersion[1].vString[11] = '\0';
14225
14226 /* DRX39xxJ type Ax */
14227 /* TODO semantics of mfx and spin are unclear */
14228 subtype = (u16_t) ((jtag >> 12) & 0xFF);
14229 mfx = (u16_t) (jtag >> 29);
14230 extAttr->vVersion[1].vMinor = 1;
14231 if (mfx == 0x03) {
14232 extAttr->vVersion[1].vPatch = mfx + 2;
14233 } else {
14234 extAttr->vVersion[1].vPatch = mfx + 1;
14235 }
14236 extAttr->vVersion[1].vString[6] = ((char)(subtype & 0xF)) + '0';
14237 extAttr->vVersion[1].vMajor = (subtype & 0x0F);
14238 subtype >>= 4;
14239 extAttr->vVersion[1].vString[5] = ((char)(subtype & 0xF)) + '0';
14240 extAttr->vVersion[1].vMajor += 10 * subtype;
14241 extAttr->vVersion[1].vString[9] = 'A';
14242 if (mfx == 0x03) {
14243 extAttr->vVersion[1].vString[10] = ((char)(mfx & 0xF)) + '2';
14244 } else {
14245 extAttr->vVersion[1].vString[10] = ((char)(mfx & 0xF)) + '1';
14246 }
14247
14248 extAttr->vListElements[1].version = &(extAttr->vVersion[1]);
14249 extAttr->vListElements[1].next = (pDRXVersionList_t) (NULL);
14250
14251 *versionList = &(extAttr->vListElements[0]);
14252
14253 return (DRX_STS_OK);
14254
14255 rw_error:
14256 *versionList = (pDRXVersionList_t) (NULL);
14257 return (DRX_STS_ERROR);
14258
14259 }
14260
14261 /*============================================================================*/
14262
14263 /**
14264 * \fn DRXStatus_t CtrlProbeDevice()
14265 * \brief Probe device, check if it is present
14266 * \param demod Pointer to demodulator instance.
14267 * \return DRXStatus_t.
14268 * \retval DRX_STS_OK a drx39xxj device has been detected.
14269 * \retval DRX_STS_ERROR no drx39xxj device detected.
14270 *
14271 * This funtion can be caled before open() and after close().
14272 *
14273 */
14274
14275 static DRXStatus_t CtrlProbeDevice(pDRXDemodInstance_t demod)
14276 {
14277 DRXPowerMode_t orgPowerMode = DRX_POWER_UP;
14278 DRXStatus_t retStatus = DRX_STS_OK;
14279 pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) (NULL);
14280
14281 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
14282
14283 if (commonAttr->isOpened == FALSE
14284 || commonAttr->currentPowerMode != DRX_POWER_UP) {
14285 pI2CDeviceAddr_t devAddr = NULL;
14286 DRXPowerMode_t powerMode = DRX_POWER_UP;
14287 u32_t jtag = 0;
14288
14289 devAddr = demod->myI2CDevAddr;
14290
14291 /* Remeber original power mode */
14292 orgPowerMode = commonAttr->currentPowerMode;
14293
14294 if (demod->myCommonAttr->isOpened == FALSE) {
14295 CHK_ERROR(PowerUpDevice(demod));
14296 commonAttr->currentPowerMode = DRX_POWER_UP;
14297 } else {
14298 /* Wake-up device, feedback from device */
14299 CHK_ERROR(CtrlPowerMode(demod, &powerMode));
14300 }
14301 /* Initialize HI, wakeup key especially */
14302 CHK_ERROR(InitHI(demod));
14303
14304 /* Check device id */
14305 RR32(devAddr, SIO_TOP_JTAGID_LO__A, &jtag);
14306 jtag = (jtag >> 12) & 0xFFFF;
14307 switch (jtag) {
14308 case 0x3931: /* fallthrough */
14309 case 0x3932: /* fallthrough */
14310 case 0x3933: /* fallthrough */
14311 case 0x3934: /* fallthrough */
14312 case 0x3941: /* fallthrough */
14313 case 0x3942: /* fallthrough */
14314 case 0x3943: /* fallthrough */
14315 case 0x3944: /* fallthrough */
14316 case 0x3945: /* fallthrough */
14317 case 0x3946:
14318 /* ok , do nothing */
14319 break;
14320 default:
14321 retStatus = DRX_STS_ERROR;
14322 break;
14323 }
14324
14325 /* Device was not opened, return to orginal powermode,
14326 feedback from device */
14327 CHK_ERROR(CtrlPowerMode(demod, &orgPowerMode));
14328 } else {
14329 /* dummy read to make this function fail in case device
14330 suddenly disappears after a succesful DRX_Open */
14331 DUMMY_READ();
14332 }
14333
14334 return (retStatus);
14335
14336 rw_error:
14337 commonAttr->currentPowerMode = orgPowerMode;
14338 return (DRX_STS_ERROR);
14339 }
14340
14341 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
14342 /*============================================================================*/
14343
14344 /**
14345 * \fn DRXStatus_t IsMCBlockAudio()
14346 * \brief Check if MC block is Audio or not Audio.
14347 * \param addr Pointer to demodulator instance.
14348 * \param audioUpload TRUE if MC block is Audio
14349 FALSE if MC block not Audio
14350 * \return Bool_t.
14351 */
14352 Bool_t IsMCBlockAudio(u32_t addr)
14353 {
14354 if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A)) {
14355 return (TRUE);
14356 }
14357 return (FALSE);
14358 }
14359
14360 /*============================================================================*/
14361
14362 /**
14363 * \fn DRXStatus_t CtrlUCodeUpload()
14364 * \brief Handle Audio or !Audio part of microcode upload.
14365 * \param demod Pointer to demodulator instance.
14366 * \param mcInfo Pointer to information about microcode data.
14367 * \param action Either UCODE_UPLOAD or UCODE_VERIFY.
14368 * \param uploadAudioMC TRUE if Audio MC need to be uploaded.
14369 FALSE if !Audio MC need to be uploaded.
14370 * \return DRXStatus_t.
14371 */
14372 static DRXStatus_t
14373 CtrlUCodeUpload(pDRXDemodInstance_t demod,
14374 pDRXUCodeInfo_t mcInfo,
14375 DRXUCodeAction_t action, Bool_t uploadAudioMC)
14376 {
14377 u16_t i = 0;
14378 u16_t mcNrOfBlks = 0;
14379 u16_t mcMagicWord = 0;
14380 pu8_t mcData = (pu8_t) (NULL);
14381 pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
14382 pDRXJData_t extAttr = (pDRXJData_t) (NULL);
14383
14384 devAddr = demod->myI2CDevAddr;
14385 extAttr = (pDRXJData_t) demod->myExtAttr;
14386
14387 /* Check arguments */
14388 if ((mcInfo == NULL) ||
14389 (mcInfo->mcData == NULL) || (mcInfo->mcSize == 0)) {
14390 return DRX_STS_INVALID_ARG;
14391 }
14392
14393 mcData = mcInfo->mcData;
14394
14395 /* Check data */
14396 mcMagicWord = UCodeRead16(mcData);
14397 mcData += sizeof(u16_t);
14398 mcNrOfBlks = UCodeRead16(mcData);
14399 mcData += sizeof(u16_t);
14400
14401 if ((mcMagicWord != DRXJ_UCODE_MAGIC_WORD) || (mcNrOfBlks == 0)) {
14402 /* wrong endianess or wrong data ? */
14403 return DRX_STS_INVALID_ARG;
14404 }
14405
14406 /* Process microcode blocks */
14407 for (i = 0; i < mcNrOfBlks; i++) {
14408 DRXUCodeBlockHdr_t blockHdr;
14409 u16_t mcBlockNrBytes = 0;
14410
14411 /* Process block header */
14412 blockHdr.addr = UCodeRead32(mcData);
14413 mcData += sizeof(u32_t);
14414 blockHdr.size = UCodeRead16(mcData);
14415 mcData += sizeof(u16_t);
14416 blockHdr.flags = UCodeRead16(mcData);
14417 mcData += sizeof(u16_t);
14418 blockHdr.CRC = UCodeRead16(mcData);
14419 mcData += sizeof(u16_t);
14420
14421 /* Check block header on:
14422 - no data
14423 - data larger then 64Kb
14424 - if CRC enabled check CRC
14425 */
14426 if ((blockHdr.size == 0) ||
14427 (blockHdr.size > 0x7FFF) ||
14428 (((blockHdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
14429 (blockHdr.CRC != UCodeComputeCRC(mcData, blockHdr.size)))
14430 ) {
14431 /* Wrong data ! */
14432 return DRX_STS_INVALID_ARG;
14433 }
14434
14435 mcBlockNrBytes = blockHdr.size * sizeof(u16_t);
14436
14437 /* Perform the desired action */
14438 /* Check which part of MC need to be uploaded - Audio or not Audio */
14439 if (IsMCBlockAudio(blockHdr.addr) == uploadAudioMC) {
14440 switch (action) {
14441 /*===================================================================*/
14442 case UCODE_UPLOAD:
14443 {
14444 /* Upload microcode */
14445 if (demod->myAccessFunct->
14446 writeBlockFunc(devAddr,
14447 (DRXaddr_t) blockHdr.
14448 addr, mcBlockNrBytes,
14449 mcData,
14450 0x0000) !=
14451 DRX_STS_OK) {
14452 return (DRX_STS_ERROR);
14453 }
14454 };
14455 break;
14456
14457 /*===================================================================*/
14458 case UCODE_VERIFY:
14459 {
14460 int result = 0;
14461 u8_t mcDataBuffer
14462 [DRXJ_UCODE_MAX_BUF_SIZE];
14463 u32_t bytesToCompare = 0;
14464 u32_t bytesLeftToCompare = 0;
14465 DRXaddr_t currAddr = (DRXaddr_t) 0;
14466 pu8_t currPtr = NULL;
14467
14468 bytesLeftToCompare = mcBlockNrBytes;
14469 currAddr = blockHdr.addr;
14470 currPtr = mcData;
14471
14472 while (bytesLeftToCompare != 0) {
14473 if (bytesLeftToCompare >
14474 ((u32_t)
14475 DRXJ_UCODE_MAX_BUF_SIZE)) {
14476 bytesToCompare =
14477 ((u32_t)
14478 DRXJ_UCODE_MAX_BUF_SIZE);
14479 } else {
14480 bytesToCompare =
14481 bytesLeftToCompare;
14482 }
14483
14484 if (demod->myAccessFunct->
14485 readBlockFunc(devAddr,
14486 currAddr,
14487 (u16_t)
14488 bytesToCompare,
14489 (pu8_t)
14490 mcDataBuffer,
14491 0x0000) !=
14492 DRX_STS_OK) {
14493 return (DRX_STS_ERROR);
14494 }
14495
14496 result =
14497 DRXBSP_HST_Memcmp(currPtr,
14498 mcDataBuffer,
14499 bytesToCompare);
14500
14501 if (result != 0) {
14502 return (DRX_STS_ERROR);
14503 };
14504
14505 currAddr +=
14506 ((DRXaddr_t)
14507 (bytesToCompare / 2));
14508 currPtr =
14509 &(currPtr[bytesToCompare]);
14510 bytesLeftToCompare -=
14511 ((u32_t) bytesToCompare);
14512 } /* while( bytesToCompare > DRXJ_UCODE_MAX_BUF_SIZE ) */
14513 };
14514 break;
14515
14516 /*===================================================================*/
14517 default:
14518 return DRX_STS_INVALID_ARG;
14519 break;
14520
14521 } /* switch ( action ) */
14522 }
14523
14524 /* if( IsMCBlockAudio( blockHdr.addr ) == uploadAudioMC ) */
14525 /* Next block */
14526 mcData += mcBlockNrBytes;
14527 } /* for( i = 0 ; i<mcNrOfBlks ; i++ ) */
14528
14529 if (uploadAudioMC == FALSE) {
14530 extAttr->flagAudMcUploaded = FALSE;
14531 }
14532
14533 return (DRX_STS_OK);
14534 }
14535 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
14536
14537 /*============================================================================*/
14538 /*== CTRL Set/Get Config related functions ===================================*/
14539 /*============================================================================*/
14540
14541 /*===== SigStrength() =========================================================*/
14542 /**
14543 * \fn DRXStatus_t CtrlSigStrength()
14544 * \brief Retrieve signal strength.
14545 * \param devmod Pointer to demodulator instance.
14546 * \param sigQuality Pointer to signal strength data; range 0, .. , 100.
14547 * \return DRXStatus_t.
14548 * \retval DRX_STS_OK sigStrength contains valid data.
14549 * \retval DRX_STS_INVALID_ARG sigStrength is NULL.
14550 * \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
14551
14552 */
14553 static DRXStatus_t
14554 CtrlSigStrength(pDRXDemodInstance_t demod, pu16_t sigStrength)
14555 {
14556 pDRXJData_t extAttr = NULL;
14557 DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
14558
14559 /* Check arguments */
14560 if ((sigStrength == NULL) || (demod == NULL)) {
14561 return (DRX_STS_INVALID_ARG);
14562 }
14563
14564 extAttr = (pDRXJData_t) demod->myExtAttr;
14565 standard = extAttr->standard;
14566 *sigStrength = 0;
14567
14568 /* Signal strength indication for each standard */
14569 switch (standard) {
14570 case DRX_STANDARD_8VSB: /* fallthrough */
14571 #ifndef DRXJ_VSB_ONLY
14572 case DRX_STANDARD_ITU_A: /* fallthrough */
14573 case DRX_STANDARD_ITU_B: /* fallthrough */
14574 case DRX_STANDARD_ITU_C:
14575 #endif
14576 CHK_ERROR(GetSigStrength(demod, sigStrength));
14577 break;
14578 #ifndef DRXJ_DIGITAL_ONLY
14579 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14580 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14581 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14582 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14583 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14584 case DRX_STANDARD_NTSC: /* fallthrough */
14585 case DRX_STANDARD_FM:
14586 CHK_ERROR(GetAtvSigStrength(demod, sigStrength));
14587 break;
14588 #endif
14589 case DRX_STANDARD_UNKNOWN: /* fallthrough */
14590 default:
14591 return (DRX_STS_INVALID_ARG);
14592 }
14593
14594 /* TODO */
14595 /* find out if signal strength is calculated in the same way for all standards */
14596 return (DRX_STS_OK);
14597 rw_error:
14598 return (DRX_STS_ERROR);
14599 }
14600
14601 /*============================================================================*/
14602 /**
14603 * \fn DRXStatus_t CtrlGetCfgOOBMisc()
14604 * \brief Get current state information of OOB.
14605 * \param pointer to DRXJCfgOOBMisc_t.
14606 * \return DRXStatus_t.
14607 *
14608 */
14609 #ifndef DRXJ_DIGITAL_ONLY
14610 static DRXStatus_t
14611 CtrlGetCfgOOBMisc(pDRXDemodInstance_t demod, pDRXJCfgOOBMisc_t misc)
14612 {
14613 pI2CDeviceAddr_t devAddr = NULL;
14614 u16_t lock = 0U;
14615 u16_t state = 0U;
14616 u16_t data = 0U;
14617 u16_t digitalAGCMant = 0U;
14618 u16_t digitalAGCExp = 0U;
14619
14620 /* check arguments */
14621 if (misc == NULL) {
14622 return (DRX_STS_INVALID_ARG);
14623 }
14624 devAddr = demod->myI2CDevAddr;
14625
14626 /* TODO */
14627 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
14628 RR16(devAddr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC);
14629 RR16(devAddr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC);
14630 RR16(devAddr, ORX_FWP_SRC_DGN_W__A, &data);
14631
14632 digitalAGCMant = data & ORX_FWP_SRC_DGN_W_MANT__M;
14633 digitalAGCExp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
14634 >> ORX_FWP_SRC_DGN_W_EXP__B;
14635 misc->agc.DigitalAGC = digitalAGCMant << digitalAGCExp;
14636
14637 SARR16(devAddr, SCU_RAM_ORX_SCU_LOCK__A, &lock);
14638
14639 misc->anaGainLock = ((lock & 0x0001) ? TRUE : FALSE);
14640 misc->digGainLock = ((lock & 0x0002) ? TRUE : FALSE);
14641 misc->freqLock = ((lock & 0x0004) ? TRUE : FALSE);
14642 misc->phaseLock = ((lock & 0x0008) ? TRUE : FALSE);
14643 misc->symTimingLock = ((lock & 0x0010) ? TRUE : FALSE);
14644 misc->eqLock = ((lock & 0x0020) ? TRUE : FALSE);
14645
14646 SARR16(devAddr, SCU_RAM_ORX_SCU_STATE__A, &state);
14647 misc->state = (state >> 8) & 0xff;
14648
14649 return (DRX_STS_OK);
14650 rw_error:
14651 return (DRX_STS_ERROR);
14652 }
14653 #endif
14654
14655 /**
14656 * \fn DRXStatus_t CtrlGetCfgVSBMisc()
14657 * \brief Get current state information of OOB.
14658 * \param pointer to DRXJCfgOOBMisc_t.
14659 * \return DRXStatus_t.
14660 *
14661 */
14662 static DRXStatus_t
14663 CtrlGetCfgVSBMisc(pDRXDemodInstance_t demod, pDRXJCfgVSBMisc_t misc)
14664 {
14665 pI2CDeviceAddr_t devAddr = NULL;
14666
14667 /* check arguments */
14668 if (misc == NULL) {
14669 return (DRX_STS_INVALID_ARG);
14670 }
14671 devAddr = demod->myI2CDevAddr;
14672
14673 CHK_ERROR(GetVSBSymbErr(devAddr, &misc->symbError));
14674
14675 return (DRX_STS_OK);
14676 rw_error:
14677 return (DRX_STS_ERROR);
14678 }
14679
14680 /*============================================================================*/
14681
14682 /**
14683 * \fn DRXStatus_t CtrlSetCfgAgcIf()
14684 * \brief Set IF AGC.
14685 * \param demod demod instance
14686 * \param agcSettings If agc configuration
14687 * \return DRXStatus_t.
14688 *
14689 * Check arguments
14690 * Dispatch handling to standard specific function.
14691 *
14692 */
14693 static DRXStatus_t
14694 CtrlSetCfgAgcIf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
14695 {
14696 /* check arguments */
14697 if (agcSettings == NULL) {
14698 return (DRX_STS_INVALID_ARG);
14699 }
14700
14701 switch (agcSettings->ctrlMode) {
14702 case DRX_AGC_CTRL_AUTO: /* fallthrough */
14703 case DRX_AGC_CTRL_USER: /* fallthrough */
14704 case DRX_AGC_CTRL_OFF: /* fallthrough */
14705 break;
14706 default:
14707 return (DRX_STS_INVALID_ARG);
14708 }
14709
14710 /* Distpatch */
14711 switch (agcSettings->standard) {
14712 case DRX_STANDARD_8VSB: /* fallthrough */
14713 #ifndef DRXJ_VSB_ONLY
14714 case DRX_STANDARD_ITU_A: /* fallthrough */
14715 case DRX_STANDARD_ITU_B: /* fallthrough */
14716 case DRX_STANDARD_ITU_C:
14717 #endif
14718 #ifndef DRXJ_DIGITAL_ONLY
14719 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14720 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14721 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14722 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14723 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14724 case DRX_STANDARD_NTSC: /* fallthrough */
14725 case DRX_STANDARD_FM:
14726 #endif
14727 return SetAgcIf(demod, agcSettings, TRUE);
14728 case DRX_STANDARD_UNKNOWN:
14729 default:
14730 return (DRX_STS_INVALID_ARG);
14731 }
14732
14733 return (DRX_STS_OK);
14734 }
14735
14736 /*============================================================================*/
14737
14738 /**
14739 * \fn DRXStatus_t CtrlGetCfgAgcIf()
14740 * \brief Retrieve IF AGC settings.
14741 * \param demod demod instance
14742 * \param agcSettings If agc configuration
14743 * \return DRXStatus_t.
14744 *
14745 * Check arguments
14746 * Dispatch handling to standard specific function.
14747 *
14748 */
14749 static DRXStatus_t
14750 CtrlGetCfgAgcIf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
14751 {
14752 /* check arguments */
14753 if (agcSettings == NULL) {
14754 return (DRX_STS_INVALID_ARG);
14755 }
14756
14757 /* Distpatch */
14758 switch (agcSettings->standard) {
14759 case DRX_STANDARD_8VSB: /* fallthrough */
14760 #ifndef DRXJ_VSB_ONLY
14761 case DRX_STANDARD_ITU_A: /* fallthrough */
14762 case DRX_STANDARD_ITU_B: /* fallthrough */
14763 case DRX_STANDARD_ITU_C:
14764 #endif
14765 #ifndef DRXJ_DIGITAL_ONLY
14766 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14767 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14768 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14769 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14770 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14771 case DRX_STANDARD_NTSC: /* fallthrough */
14772 case DRX_STANDARD_FM:
14773 #endif
14774 return GetAgcIf(demod, agcSettings);
14775 case DRX_STANDARD_UNKNOWN:
14776 default:
14777 return (DRX_STS_INVALID_ARG);
14778 }
14779
14780 return (DRX_STS_OK);
14781 }
14782
14783 /*============================================================================*/
14784
14785 /**
14786 * \fn DRXStatus_t CtrlSetCfgAgcRf()
14787 * \brief Set RF AGC.
14788 * \param demod demod instance
14789 * \param agcSettings rf agc configuration
14790 * \return DRXStatus_t.
14791 *
14792 * Check arguments
14793 * Dispatch handling to standard specific function.
14794 *
14795 */
14796 static DRXStatus_t
14797 CtrlSetCfgAgcRf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
14798 {
14799 /* check arguments */
14800 if (agcSettings == NULL) {
14801 return (DRX_STS_INVALID_ARG);
14802 }
14803
14804 switch (agcSettings->ctrlMode) {
14805 case DRX_AGC_CTRL_AUTO: /* fallthrough */
14806 case DRX_AGC_CTRL_USER: /* fallthrough */
14807 case DRX_AGC_CTRL_OFF:
14808 break;
14809 default:
14810 return (DRX_STS_INVALID_ARG);
14811 }
14812
14813 /* Distpatch */
14814 switch (agcSettings->standard) {
14815 case DRX_STANDARD_8VSB: /* fallthrough */
14816 #ifndef DRXJ_VSB_ONLY
14817 case DRX_STANDARD_ITU_A: /* fallthrough */
14818 case DRX_STANDARD_ITU_B: /* fallthrough */
14819 case DRX_STANDARD_ITU_C:
14820 #endif
14821 #ifndef DRXJ_DIGITAL_ONLY
14822 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14823 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14824 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14825 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14826 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14827 case DRX_STANDARD_NTSC: /* fallthrough */
14828 case DRX_STANDARD_FM:
14829 #endif
14830 return SetAgcRf(demod, agcSettings, TRUE);
14831 case DRX_STANDARD_UNKNOWN:
14832 default:
14833 return (DRX_STS_INVALID_ARG);
14834 }
14835
14836 return (DRX_STS_OK);
14837 }
14838
14839 /*============================================================================*/
14840
14841 /**
14842 * \fn DRXStatus_t CtrlGetCfgAgcRf()
14843 * \brief Retrieve RF AGC settings.
14844 * \param demod demod instance
14845 * \param agcSettings Rf agc configuration
14846 * \return DRXStatus_t.
14847 *
14848 * Check arguments
14849 * Dispatch handling to standard specific function.
14850 *
14851 */
14852 static DRXStatus_t
14853 CtrlGetCfgAgcRf(pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings)
14854 {
14855 /* check arguments */
14856 if (agcSettings == NULL) {
14857 return (DRX_STS_INVALID_ARG);
14858 }
14859
14860 /* Distpatch */
14861 switch (agcSettings->standard) {
14862 case DRX_STANDARD_8VSB: /* fallthrough */
14863 #ifndef DRXJ_VSB_ONLY
14864 case DRX_STANDARD_ITU_A: /* fallthrough */
14865 case DRX_STANDARD_ITU_B: /* fallthrough */
14866 case DRX_STANDARD_ITU_C:
14867 #endif
14868 #ifndef DRXJ_DIGITAL_ONLY
14869 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14870 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14871 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14872 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14873 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14874 case DRX_STANDARD_NTSC: /* fallthrough */
14875 case DRX_STANDARD_FM:
14876 #endif
14877 return GetAgcRf(demod, agcSettings);
14878 case DRX_STANDARD_UNKNOWN:
14879 default:
14880 return (DRX_STS_INVALID_ARG);
14881 }
14882
14883 return (DRX_STS_OK);
14884 }
14885
14886 /*============================================================================*/
14887
14888 /**
14889 * \fn DRXStatus_t CtrlGetCfgAgcInternal()
14890 * \brief Retrieve internal AGC value.
14891 * \param demod demod instance
14892 * \param u16_t
14893 * \return DRXStatus_t.
14894 *
14895 * Check arguments
14896 * Dispatch handling to standard specific function.
14897 *
14898 */
14899 static DRXStatus_t
14900 CtrlGetCfgAgcInternal(pDRXDemodInstance_t demod, pu16_t agcInternal)
14901 {
14902 pI2CDeviceAddr_t devAddr = NULL;
14903 DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
14904 pDRXJData_t extAttr = NULL;
14905 u16_t iqmCfScaleSh = 0;
14906 u16_t iqmCfPower = 0;
14907 u16_t iqmCfAmp = 0;
14908 u16_t iqmCfGain = 0;
14909
14910 /* check arguments */
14911 if (agcInternal == NULL) {
14912 return (DRX_STS_INVALID_ARG);
14913 }
14914 devAddr = demod->myI2CDevAddr;
14915 extAttr = (pDRXJData_t) demod->myExtAttr;
14916
14917 CHK_ERROR(CtrlLockStatus(demod, &lockStatus));
14918 if (lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED) {
14919 *agcInternal = 0;
14920 return DRX_STS_OK;
14921 }
14922
14923 /* Distpatch */
14924 switch (extAttr->standard) {
14925 case DRX_STANDARD_8VSB:
14926 iqmCfGain = 57;
14927 break;
14928 #ifndef DRXJ_VSB_ONLY
14929 case DRX_STANDARD_ITU_A:
14930 case DRX_STANDARD_ITU_B:
14931 case DRX_STANDARD_ITU_C:
14932 switch (extAttr->constellation) {
14933 case DRX_CONSTELLATION_QAM256:
14934 case DRX_CONSTELLATION_QAM128:
14935 case DRX_CONSTELLATION_QAM32:
14936 case DRX_CONSTELLATION_QAM16:
14937 iqmCfGain = 57;
14938 break;
14939 case DRX_CONSTELLATION_QAM64:
14940 iqmCfGain = 56;
14941 break;
14942 default:
14943 return (DRX_STS_ERROR);
14944 }
14945 break;
14946 #endif
14947 default:
14948 return (DRX_STS_INVALID_ARG);
14949 }
14950
14951 RR16(devAddr, IQM_CF_POW__A, &iqmCfPower);
14952 RR16(devAddr, IQM_CF_SCALE_SH__A, &iqmCfScaleSh);
14953 RR16(devAddr, IQM_CF_AMP__A, &iqmCfAmp);
14954 /* IQM_CF_PWR_CORRECTION_dB = 3;
14955 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
14956 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
14957 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
14958 +6*7+10*log10(1+0.115/4); */
14959 /* PadcdB = P4dB +3 -6 +60; dBmV */
14960 *agcInternal = (u16_t) (Log10Times100(iqmCfPower)
14961 - 2 * Log10Times100(iqmCfAmp)
14962 - iqmCfGain - 120 * iqmCfScaleSh + 781);
14963
14964 return (DRX_STS_OK);
14965 rw_error:
14966 return (DRX_STS_ERROR);
14967 }
14968
14969 /*============================================================================*/
14970
14971 /**
14972 * \fn DRXStatus_t CtrlSetCfgPreSaw()
14973 * \brief Set Pre-saw reference.
14974 * \param demod demod instance
14975 * \param pu16_t
14976 * \return DRXStatus_t.
14977 *
14978 * Check arguments
14979 * Dispatch handling to standard specific function.
14980 *
14981 */
14982 static DRXStatus_t
14983 CtrlSetCfgPreSaw(pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw)
14984 {
14985 pI2CDeviceAddr_t devAddr = NULL;
14986 pDRXJData_t extAttr = NULL;
14987
14988 devAddr = demod->myI2CDevAddr;
14989 extAttr = (pDRXJData_t) demod->myExtAttr;
14990
14991 /* check arguments */
14992 if ((preSaw == NULL) || (preSaw->reference > IQM_AF_PDREF__M)
14993 ) {
14994 return (DRX_STS_INVALID_ARG);
14995 }
14996
14997 /* Only if standard is currently active */
14998 if ((extAttr->standard == preSaw->standard) ||
14999 (DRXJ_ISQAMSTD(extAttr->standard) &&
15000 DRXJ_ISQAMSTD(preSaw->standard)) ||
15001 (DRXJ_ISATVSTD(extAttr->standard) &&
15002 DRXJ_ISATVSTD(preSaw->standard))) {
15003 WR16(devAddr, IQM_AF_PDREF__A, preSaw->reference);
15004 }
15005
15006 /* Store pre-saw settings */
15007 switch (preSaw->standard) {
15008 case DRX_STANDARD_8VSB:
15009 extAttr->vsbPreSawCfg = *preSaw;
15010 break;
15011 #ifndef DRXJ_VSB_ONLY
15012 case DRX_STANDARD_ITU_A: /* fallthrough */
15013 case DRX_STANDARD_ITU_B: /* fallthrough */
15014 case DRX_STANDARD_ITU_C:
15015 extAttr->qamPreSawCfg = *preSaw;
15016 break;
15017 #endif
15018 #ifndef DRXJ_DIGITAL_ONLY
15019 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
15020 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
15021 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
15022 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
15023 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
15024 case DRX_STANDARD_NTSC: /* fallthrough */
15025 case DRX_STANDARD_FM:
15026 extAttr->atvPreSawCfg = *preSaw;
15027 break;
15028 #endif
15029 default:
15030 return (DRX_STS_INVALID_ARG);
15031 }
15032
15033 return (DRX_STS_OK);
15034 rw_error:
15035 return (DRX_STS_ERROR);
15036 }
15037
15038 /*============================================================================*/
15039
15040 /**
15041 * \fn DRXStatus_t CtrlSetCfgAfeGain()
15042 * \brief Set AFE Gain.
15043 * \param demod demod instance
15044 * \param pu16_t
15045 * \return DRXStatus_t.
15046 *
15047 * Check arguments
15048 * Dispatch handling to standard specific function.
15049 *
15050 */
15051 static DRXStatus_t
15052 CtrlSetCfgAfeGain(pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain)
15053 {
15054 pI2CDeviceAddr_t devAddr = NULL;
15055 pDRXJData_t extAttr = NULL;
15056 u8_t gain = 0;
15057
15058 /* check arguments */
15059 if (afeGain == NULL) {
15060 return (DRX_STS_INVALID_ARG);
15061 }
15062
15063 devAddr = demod->myI2CDevAddr;
15064 extAttr = (pDRXJData_t) demod->myExtAttr;
15065
15066 switch (afeGain->standard) {
15067 case DRX_STANDARD_8VSB: /* fallthrough */
15068 #ifndef DRXJ_VSB_ONLY
15069 case DRX_STANDARD_ITU_A: /* fallthrough */
15070 case DRX_STANDARD_ITU_B: /* fallthrough */
15071 case DRX_STANDARD_ITU_C:
15072 #endif
15073 /* Do nothing */
15074 break;
15075 default:
15076 return (DRX_STS_INVALID_ARG);
15077 }
15078
15079 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
15080 So I (PJ) think interface requires choice between auto, user mode */
15081
15082 if (afeGain->gain >= 329)
15083 gain = 15;
15084 else if (afeGain->gain <= 147)
15085 gain = 0;
15086 else
15087 gain = (afeGain->gain - 140 + 6) / 13;
15088
15089 /* Only if standard is currently active */
15090 if (extAttr->standard == afeGain->standard)
15091 WR16(devAddr, IQM_AF_PGA_GAIN__A, gain);
15092
15093 /* Store AFE Gain settings */
15094 switch (afeGain->standard) {
15095 case DRX_STANDARD_8VSB:
15096 extAttr->vsbPgaCfg = gain * 13 + 140;
15097 break;
15098 #ifndef DRXJ_VSB_ONLY
15099 case DRX_STANDARD_ITU_A: /* fallthrough */
15100 case DRX_STANDARD_ITU_B: /* fallthrough */
15101 case DRX_STANDARD_ITU_C:
15102 extAttr->qamPgaCfg = gain * 13 + 140;
15103 break;
15104 #endif
15105 default:
15106 return (DRX_STS_ERROR);
15107 }
15108
15109 return (DRX_STS_OK);
15110 rw_error:
15111 return (DRX_STS_ERROR);
15112 }
15113
15114 /*============================================================================*/
15115
15116 /**
15117 * \fn DRXStatus_t CtrlGetCfgPreSaw()
15118 * \brief Get Pre-saw reference setting.
15119 * \param demod demod instance
15120 * \param pu16_t
15121 * \return DRXStatus_t.
15122 *
15123 * Check arguments
15124 * Dispatch handling to standard specific function.
15125 *
15126 */
15127 static DRXStatus_t
15128 CtrlGetCfgPreSaw(pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw)
15129 {
15130 pI2CDeviceAddr_t devAddr = NULL;
15131 pDRXJData_t extAttr = NULL;
15132
15133 /* check arguments */
15134 if (preSaw == NULL) {
15135 return (DRX_STS_INVALID_ARG);
15136 }
15137
15138 devAddr = demod->myI2CDevAddr;
15139 extAttr = (pDRXJData_t) demod->myExtAttr;
15140
15141 switch (preSaw->standard) {
15142 case DRX_STANDARD_8VSB:
15143 *preSaw = extAttr->vsbPreSawCfg;
15144 break;
15145 #ifndef DRXJ_VSB_ONLY
15146 case DRX_STANDARD_ITU_A: /* fallthrough */
15147 case DRX_STANDARD_ITU_B: /* fallthrough */
15148 case DRX_STANDARD_ITU_C:
15149 *preSaw = extAttr->qamPreSawCfg;
15150 break;
15151 #endif
15152 #ifndef DRXJ_DIGITAL_ONLY
15153 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
15154 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
15155 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
15156 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
15157 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
15158 case DRX_STANDARD_NTSC:
15159 extAttr->atvPreSawCfg.standard = DRX_STANDARD_NTSC;
15160 *preSaw = extAttr->atvPreSawCfg;
15161 break;
15162 case DRX_STANDARD_FM:
15163 extAttr->atvPreSawCfg.standard = DRX_STANDARD_FM;
15164 *preSaw = extAttr->atvPreSawCfg;
15165 break;
15166 #endif
15167 default:
15168 return (DRX_STS_INVALID_ARG);
15169 }
15170
15171 return (DRX_STS_OK);
15172 }
15173
15174 /*============================================================================*/
15175
15176 /**
15177 * \fn DRXStatus_t CtrlGetCfgAfeGain()
15178 * \brief Get AFE Gain.
15179 * \param demod demod instance
15180 * \param pu16_t
15181 * \return DRXStatus_t.
15182 *
15183 * Check arguments
15184 * Dispatch handling to standard specific function.
15185 *
15186 */
15187 static DRXStatus_t
15188 CtrlGetCfgAfeGain(pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain)
15189 {
15190 pI2CDeviceAddr_t devAddr = NULL;
15191 pDRXJData_t extAttr = NULL;
15192
15193 /* check arguments */
15194 if (afeGain == NULL) {
15195 return (DRX_STS_INVALID_ARG);
15196 }
15197
15198 devAddr = demod->myI2CDevAddr;
15199 extAttr = (pDRXJData_t) demod->myExtAttr;
15200
15201 switch (afeGain->standard) {
15202 case DRX_STANDARD_8VSB:
15203 afeGain->gain = extAttr->vsbPgaCfg;
15204 break;
15205 #ifndef DRXJ_VSB_ONLY
15206 case DRX_STANDARD_ITU_A: /* fallthrough */
15207 case DRX_STANDARD_ITU_B: /* fallthrough */
15208 case DRX_STANDARD_ITU_C:
15209 afeGain->gain = extAttr->qamPgaCfg;
15210 break;
15211 #endif
15212 default:
15213 return (DRX_STS_INVALID_ARG);
15214 }
15215
15216 return (DRX_STS_OK);
15217 }
15218
15219 /*============================================================================*/
15220
15221 /**
15222 * \fn DRXStatus_t CtrlGetFecMeasSeqCount()
15223 * \brief Get FEC measurement sequnce number.
15224 * \param demod demod instance
15225 * \param pu16_t
15226 * \return DRXStatus_t.
15227 *
15228 * Check arguments
15229 * Dispatch handling to standard specific function.
15230 *
15231 */
15232 static DRXStatus_t
15233 CtrlGetFecMeasSeqCount(pDRXDemodInstance_t demod, pu16_t fecMeasSeqCount)
15234 {
15235 /* check arguments */
15236 if (fecMeasSeqCount == NULL) {
15237 return (DRX_STS_INVALID_ARG);
15238 }
15239
15240 RR16(demod->myI2CDevAddr, SCU_RAM_FEC_MEAS_COUNT__A, fecMeasSeqCount);
15241
15242 return (DRX_STS_OK);
15243 rw_error:
15244 return (DRX_STS_ERROR);
15245 }
15246
15247 /*============================================================================*/
15248
15249 /**
15250 * \fn DRXStatus_t CtrlGetAccumCrRSCwErr()
15251 * \brief Get accumulative corrected RS codeword number.
15252 * \param demod demod instance
15253 * \param pu32_t
15254 * \return DRXStatus_t.
15255 *
15256 * Check arguments
15257 * Dispatch handling to standard specific function.
15258 *
15259 */
15260 static DRXStatus_t
15261 CtrlGetAccumCrRSCwErr(pDRXDemodInstance_t demod, pu32_t accumCrRsCWErr)
15262 {
15263 if (accumCrRsCWErr == NULL) {
15264 return (DRX_STS_INVALID_ARG);
15265 }
15266
15267 RR32(demod->myI2CDevAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A,
15268 accumCrRsCWErr);
15269
15270 return (DRX_STS_OK);
15271 rw_error:
15272 return (DRX_STS_ERROR);
15273 }
15274
15275 /**
15276 * \fn DRXStatus_t CtrlSetCfg()
15277 * \brief Set 'some' configuration of the device.
15278 * \param devmod Pointer to demodulator instance.
15279 * \param config Pointer to configuration parameters (type and data).
15280 * \return DRXStatus_t.
15281
15282 */
15283 static DRXStatus_t CtrlSetCfg(pDRXDemodInstance_t demod, pDRXCfg_t config)
15284 {
15285 if (config == NULL) {
15286 return (DRX_STS_INVALID_ARG);
15287 }
15288
15289 DUMMY_READ();
15290 switch (config->cfgType) {
15291 case DRX_CFG_MPEG_OUTPUT:
15292 return CtrlSetCfgMPEGOutput(demod,
15293 (pDRXCfgMPEGOutput_t) config->
15294 cfgData);
15295 case DRX_CFG_PINS_SAFE_MODE:
15296 return CtrlSetCfgPdrSafeMode(demod, (pBool_t) config->cfgData);
15297 case DRXJ_CFG_AGC_RF:
15298 return CtrlSetCfgAgcRf(demod, (pDRXJCfgAgc_t) config->cfgData);
15299 case DRXJ_CFG_AGC_IF:
15300 return CtrlSetCfgAgcIf(demod, (pDRXJCfgAgc_t) config->cfgData);
15301 case DRXJ_CFG_PRE_SAW:
15302 return CtrlSetCfgPreSaw(demod,
15303 (pDRXJCfgPreSaw_t) config->cfgData);
15304 case DRXJ_CFG_AFE_GAIN:
15305 return CtrlSetCfgAfeGain(demod,
15306 (pDRXJCfgAfeGain_t) config->cfgData);
15307 case DRXJ_CFG_SMART_ANT:
15308 return CtrlSetCfgSmartAnt(demod,
15309 (pDRXJCfgSmartAnt_t) (config->
15310 cfgData));
15311 case DRXJ_CFG_RESET_PACKET_ERR:
15312 return CtrlSetCfgResetPktErr(demod);
15313 #ifndef DRXJ_DIGITAL_ONLY
15314 case DRXJ_CFG_OOB_PRE_SAW:
15315 return CtrlSetCfgOOBPreSAW(demod, (pu16_t) (config->cfgData));
15316 case DRXJ_CFG_OOB_LO_POW:
15317 return CtrlSetCfgOOBLoPower(demod,
15318 (pDRXJCfgOobLoPower_t) (config->
15319 cfgData));
15320 case DRXJ_CFG_ATV_MISC:
15321 return CtrlSetCfgAtvMisc(demod,
15322 (pDRXJCfgAtvMisc_t) config->cfgData);
15323 case DRXJ_CFG_ATV_EQU_COEF:
15324 return CtrlSetCfgAtvEquCoef(demod,
15325 (pDRXJCfgAtvEquCoef_t) config->
15326 cfgData);
15327 case DRXJ_CFG_ATV_OUTPUT:
15328 return CtrlSetCfgATVOutput(demod,
15329 (pDRXJCfgAtvOutput_t) config->
15330 cfgData);
15331 #endif
15332 case DRXJ_CFG_MPEG_OUTPUT_MISC:
15333 return CtrlSetCfgMpegOutputMisc(demod,
15334 (pDRXJCfgMpegOutputMisc_t)
15335 config->cfgData);
15336 #ifndef DRXJ_EXCLUDE_AUDIO
15337 case DRX_CFG_AUD_VOLUME:
15338 return AUDCtrlSetCfgVolume(demod,
15339 (pDRXCfgAudVolume_t) config->
15340 cfgData);
15341 case DRX_CFG_I2S_OUTPUT:
15342 return AUDCtrlSetCfgOutputI2S(demod,
15343 (pDRXCfgI2SOutput_t) config->
15344 cfgData);
15345 case DRX_CFG_AUD_AUTOSOUND:
15346 return AUDCtrSetlCfgAutoSound(demod, (pDRXCfgAudAutoSound_t)
15347 config->cfgData);
15348 case DRX_CFG_AUD_ASS_THRES:
15349 return AUDCtrlSetCfgASSThres(demod, (pDRXCfgAudASSThres_t)
15350 config->cfgData);
15351 case DRX_CFG_AUD_CARRIER:
15352 return AUDCtrlSetCfgCarrier(demod,
15353 (pDRXCfgAudCarriers_t) config->
15354 cfgData);
15355 case DRX_CFG_AUD_DEVIATION:
15356 return AUDCtrlSetCfgDev(demod,
15357 (pDRXCfgAudDeviation_t) config->
15358 cfgData);
15359 case DRX_CFG_AUD_PRESCALE:
15360 return AUDCtrlSetCfgPrescale(demod,
15361 (pDRXCfgAudPrescale_t) config->
15362 cfgData);
15363 case DRX_CFG_AUD_MIXER:
15364 return AUDCtrlSetCfgMixer(demod,
15365 (pDRXCfgAudMixer_t) config->cfgData);
15366 case DRX_CFG_AUD_AVSYNC:
15367 return AUDCtrlSetCfgAVSync(demod,
15368 (pDRXCfgAudAVSync_t) config->
15369 cfgData);
15370
15371 #endif
15372 default:
15373 return (DRX_STS_INVALID_ARG);
15374 }
15375
15376 return (DRX_STS_OK);
15377 rw_error:
15378 return (DRX_STS_ERROR);
15379 }
15380
15381 /*============================================================================*/
15382
15383 /**
15384 * \fn DRXStatus_t CtrlGetCfg()
15385 * \brief Get 'some' configuration of the device.
15386 * \param devmod Pointer to demodulator instance.
15387 * \param config Pointer to configuration parameters (type and data).
15388 * \return DRXStatus_t.
15389 */
15390
15391 static DRXStatus_t CtrlGetCfg(pDRXDemodInstance_t demod, pDRXCfg_t config)
15392 {
15393 if (config == NULL) {
15394 return (DRX_STS_INVALID_ARG);
15395 }
15396
15397 DUMMY_READ();
15398
15399 switch (config->cfgType) {
15400 case DRX_CFG_MPEG_OUTPUT:
15401 return CtrlGetCfgMPEGOutput(demod,
15402 (pDRXCfgMPEGOutput_t) config->
15403 cfgData);
15404 case DRX_CFG_PINS_SAFE_MODE:
15405 return CtrlGetCfgPdrSafeMode(demod, (pBool_t) config->cfgData);
15406 case DRXJ_CFG_AGC_RF:
15407 return CtrlGetCfgAgcRf(demod, (pDRXJCfgAgc_t) config->cfgData);
15408 case DRXJ_CFG_AGC_IF:
15409 return CtrlGetCfgAgcIf(demod, (pDRXJCfgAgc_t) config->cfgData);
15410 case DRXJ_CFG_AGC_INTERNAL:
15411 return CtrlGetCfgAgcInternal(demod, (pu16_t) config->cfgData);
15412 case DRXJ_CFG_PRE_SAW:
15413 return CtrlGetCfgPreSaw(demod,
15414 (pDRXJCfgPreSaw_t) config->cfgData);
15415 case DRXJ_CFG_AFE_GAIN:
15416 return CtrlGetCfgAfeGain(demod,
15417 (pDRXJCfgAfeGain_t) config->cfgData);
15418 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
15419 return CtrlGetAccumCrRSCwErr(demod, (pu32_t) config->cfgData);
15420 case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
15421 return CtrlGetFecMeasSeqCount(demod, (pu16_t) config->cfgData);
15422 case DRXJ_CFG_VSB_MISC:
15423 return CtrlGetCfgVSBMisc(demod,
15424 (pDRXJCfgVSBMisc_t) config->cfgData);
15425 case DRXJ_CFG_SYMBOL_CLK_OFFSET:
15426 return CtrlGetCfgSymbolClockOffset(demod,
15427 (ps32_t) config->cfgData);
15428 #ifndef DRXJ_DIGITAL_ONLY
15429 case DRXJ_CFG_OOB_MISC:
15430 return CtrlGetCfgOOBMisc(demod,
15431 (pDRXJCfgOOBMisc_t) config->cfgData);
15432 case DRXJ_CFG_OOB_PRE_SAW:
15433 return CtrlGetCfgOOBPreSAW(demod, (pu16_t) (config->cfgData));
15434 case DRXJ_CFG_OOB_LO_POW:
15435 return CtrlGetCfgOOBLoPower(demod,
15436 (pDRXJCfgOobLoPower_t) (config->
15437 cfgData));
15438 case DRXJ_CFG_ATV_EQU_COEF:
15439 return CtrlGetCfgAtvEquCoef(demod,
15440 (pDRXJCfgAtvEquCoef_t) config->
15441 cfgData);
15442 case DRXJ_CFG_ATV_MISC:
15443 return CtrlGetCfgAtvMisc(demod,
15444 (pDRXJCfgAtvMisc_t) config->cfgData);
15445 case DRXJ_CFG_ATV_OUTPUT:
15446 return CtrlGetCfgAtvOutput(demod,
15447 (pDRXJCfgAtvOutput_t) config->
15448 cfgData);
15449 case DRXJ_CFG_ATV_AGC_STATUS:
15450 return CtrlGetCfgAtvAgcStatus(demod,
15451 (pDRXJCfgAtvAgcStatus_t) config->
15452 cfgData);
15453 #endif
15454 case DRXJ_CFG_MPEG_OUTPUT_MISC:
15455 return CtrlGetCfgMpegOutputMisc(demod,
15456 (pDRXJCfgMpegOutputMisc_t)
15457 config->cfgData);
15458 case DRXJ_CFG_HW_CFG:
15459 return CtrlGetCfgHwCfg(demod,
15460 (pDRXJCfgHwCfg_t) config->cfgData);
15461 #ifndef DRXJ_EXCLUDE_AUDIO
15462 case DRX_CFG_AUD_VOLUME:
15463 return AUDCtrlGetCfgVolume(demod,
15464 (pDRXCfgAudVolume_t) config->
15465 cfgData);
15466 case DRX_CFG_I2S_OUTPUT:
15467 return AUDCtrlGetCfgOutputI2S(demod,
15468 (pDRXCfgI2SOutput_t) config->
15469 cfgData);
15470
15471 case DRX_CFG_AUD_RDS:
15472 return AUDCtrlGetCfgRDS(demod,
15473 (pDRXCfgAudRDS_t) config->cfgData);
15474 case DRX_CFG_AUD_AUTOSOUND:
15475 return AUDCtrlGetCfgAutoSound(demod,
15476 (pDRXCfgAudAutoSound_t) config->
15477 cfgData);
15478 case DRX_CFG_AUD_ASS_THRES:
15479 return AUDCtrlGetCfgASSThres(demod,
15480 (pDRXCfgAudASSThres_t) config->
15481 cfgData);
15482 case DRX_CFG_AUD_CARRIER:
15483 return AUDCtrlGetCfgCarrier(demod,
15484 (pDRXCfgAudCarriers_t) config->
15485 cfgData);
15486 case DRX_CFG_AUD_DEVIATION:
15487 return AUDCtrlGetCfgDev(demod,
15488 (pDRXCfgAudDeviation_t) config->
15489 cfgData);
15490 case DRX_CFG_AUD_PRESCALE:
15491 return AUDCtrlGetCfgPrescale(demod,
15492 (pDRXCfgAudPrescale_t) config->
15493 cfgData);
15494 case DRX_CFG_AUD_MIXER:
15495 return AUDCtrlGetCfgMixer(demod,
15496 (pDRXCfgAudMixer_t) config->cfgData);
15497 case DRX_CFG_AUD_AVSYNC:
15498 return AUDCtrlGetCfgAVSync(demod,
15499 (pDRXCfgAudAVSync_t) config->
15500 cfgData);
15501 #endif
15502
15503 default:
15504 return (DRX_STS_INVALID_ARG);
15505 }
15506
15507 return (DRX_STS_OK);
15508 rw_error:
15509 return (DRX_STS_ERROR);
15510 }
15511
15512 /*=============================================================================
15513 ===== EXPORTED FUNCTIONS ====================================================*/
15514 /**
15515 * \fn DRXJ_Open()
15516 * \brief Open the demod instance, configure device, configure drxdriver
15517 * \return Status_t Return status.
15518 *
15519 * DRXJ_Open() can be called with a NULL ucode image => no ucode upload.
15520 * This means that DRXJ_Open() must NOT contain SCU commands or, in general,
15521 * rely on SCU or AUD ucode to be present.
15522 *
15523 */
15524 DRXStatus_t DRXJ_Open(pDRXDemodInstance_t demod)
15525 {
15526 pI2CDeviceAddr_t devAddr = NULL;
15527 pDRXJData_t extAttr = NULL;
15528 pDRXCommonAttr_t commonAttr = NULL;
15529 u32_t driverVersion = 0;
15530 DRXUCodeInfo_t ucodeInfo;
15531 DRXCfgMPEGOutput_t cfgMPEGOutput;
15532
15533 /* Check arguments */
15534 if (demod->myExtAttr == NULL) {
15535 return (DRX_STS_INVALID_ARG);
15536 }
15537
15538 devAddr = demod->myI2CDevAddr;
15539 extAttr = (pDRXJData_t) demod->myExtAttr;
15540 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
15541
15542 CHK_ERROR(PowerUpDevice(demod));
15543 commonAttr->currentPowerMode = DRX_POWER_UP;
15544
15545 /* has to be in front of setIqmAf and setOrxNsuAox */
15546 CHK_ERROR(GetDeviceCapabilities(demod));
15547
15548 /* Soft reset of sys- and osc-clockdomain */
15549 WR16(devAddr, SIO_CC_SOFT_RST__A, (SIO_CC_SOFT_RST_SYS__M |
15550 SIO_CC_SOFT_RST_OSC__M));
15551 WR16(devAddr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
15552 CHK_ERROR(DRXBSP_HST_Sleep(1));
15553
15554 /* TODO first make sure that everything keeps working before enabling this */
15555 /* PowerDownAnalogBlocks() */
15556 WR16(devAddr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
15557 | ATV_TOP_STDBY_SIF_STDBY_STANDBY);
15558
15559 CHK_ERROR(SetIqmAf(demod, FALSE));
15560 CHK_ERROR(SetOrxNsuAox(demod, FALSE));
15561
15562 CHK_ERROR(InitHI(demod));
15563
15564 /* disable mpegoutput pins */
15565 cfgMPEGOutput.enableMPEGOutput = FALSE;
15566 CHK_ERROR(CtrlSetCfgMPEGOutput(demod, &cfgMPEGOutput));
15567 /* Stop AUD Inform SetAudio it will need to do all setting */
15568 CHK_ERROR(PowerDownAud(demod));
15569 /* Stop SCU */
15570 WR16(devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
15571
15572 /* Upload microcode */
15573 if (commonAttr->microcode != NULL) {
15574 /* Dirty trick to use common ucode upload & verify,
15575 pretend device is already open */
15576 commonAttr->isOpened = TRUE;
15577 ucodeInfo.mcData = commonAttr->microcode;
15578 ucodeInfo.mcSize = commonAttr->microcodeSize;
15579
15580 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
15581 /* Upload microcode without audio part */
15582 CHK_ERROR(CtrlUCodeUpload
15583 (demod, &ucodeInfo, UCODE_UPLOAD, FALSE));
15584 #else
15585 CHK_ERROR(DRX_Ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucodeInfo));
15586 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
15587 if (commonAttr->verifyMicrocode == TRUE) {
15588 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
15589 CHK_ERROR(CtrlUCodeUpload
15590 (demod, &ucodeInfo, UCODE_VERIFY, FALSE));
15591 #else
15592 CHK_ERROR(DRX_Ctrl
15593 (demod, DRX_CTRL_VERIFY_UCODE, &ucodeInfo));
15594 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
15595 }
15596 commonAttr->isOpened = FALSE;
15597 }
15598
15599 /* Run SCU for a little while to initialize microcode version numbers */
15600 WR16(devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
15601
15602 /* Open tuner instance */
15603 if (demod->myTuner != NULL) {
15604 demod->myTuner->myCommonAttr->myUserData = (void *)demod;
15605
15606 if (commonAttr->tunerPortNr == 1) {
15607 Bool_t bridgeClosed = TRUE;
15608 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
15609 }
15610
15611 CHK_ERROR(DRXBSP_TUNER_Open(demod->myTuner));
15612
15613 if (commonAttr->tunerPortNr == 1) {
15614 Bool_t bridgeClosed = FALSE;
15615 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
15616 }
15617 commonAttr->tunerMinFreqRF =
15618 ((demod->myTuner)->myCommonAttr->minFreqRF);
15619 commonAttr->tunerMaxFreqRF =
15620 ((demod->myTuner)->myCommonAttr->maxFreqRF);
15621 }
15622
15623 /* Initialize scan timeout */
15624 commonAttr->scanDemodLockTimeout = DRXJ_SCAN_TIMEOUT;
15625 commonAttr->scanDesiredLock = DRX_LOCKED;
15626
15627 /* Initialize default AFE configuartion for QAM */
15628 if (extAttr->hasLNA) {
15629 /* IF AGC off, PGA active */
15630 #ifndef DRXJ_VSB_ONLY
15631 extAttr->qamIfAgcCfg.standard = DRX_STANDARD_ITU_B;
15632 extAttr->qamIfAgcCfg.ctrlMode = DRX_AGC_CTRL_OFF;
15633 extAttr->qamPgaCfg = 140 + (11 * 13);
15634 #endif
15635 extAttr->vsbIfAgcCfg.standard = DRX_STANDARD_8VSB;
15636 extAttr->vsbIfAgcCfg.ctrlMode = DRX_AGC_CTRL_OFF;
15637 extAttr->vsbPgaCfg = 140 + (11 * 13);
15638 } else {
15639 /* IF AGC on, PGA not active */
15640 #ifndef DRXJ_VSB_ONLY
15641 extAttr->qamIfAgcCfg.standard = DRX_STANDARD_ITU_B;
15642 extAttr->qamIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15643 extAttr->qamIfAgcCfg.minOutputLevel = 0;
15644 extAttr->qamIfAgcCfg.maxOutputLevel = 0x7FFF;
15645 extAttr->qamIfAgcCfg.speed = 3;
15646 extAttr->qamIfAgcCfg.top = 1297;
15647 extAttr->qamPgaCfg = 140;
15648 #endif
15649 extAttr->vsbIfAgcCfg.standard = DRX_STANDARD_8VSB;
15650 extAttr->vsbIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15651 extAttr->vsbIfAgcCfg.minOutputLevel = 0;
15652 extAttr->vsbIfAgcCfg.maxOutputLevel = 0x7FFF;
15653 extAttr->vsbIfAgcCfg.speed = 3;
15654 extAttr->vsbIfAgcCfg.top = 1024;
15655 extAttr->vsbPgaCfg = 140;
15656 }
15657 /* TODO: remove minOutputLevel and maxOutputLevel for both QAM and VSB after */
15658 /* mc has not used them */
15659 #ifndef DRXJ_VSB_ONLY
15660 extAttr->qamRfAgcCfg.standard = DRX_STANDARD_ITU_B;
15661 extAttr->qamRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15662 extAttr->qamRfAgcCfg.minOutputLevel = 0;
15663 extAttr->qamRfAgcCfg.maxOutputLevel = 0x7FFF;
15664 extAttr->qamRfAgcCfg.speed = 3;
15665 extAttr->qamRfAgcCfg.top = 9500;
15666 extAttr->qamRfAgcCfg.cutOffCurrent = 4000;
15667 extAttr->qamPreSawCfg.standard = DRX_STANDARD_ITU_B;
15668 extAttr->qamPreSawCfg.reference = 0x07;
15669 extAttr->qamPreSawCfg.usePreSaw = TRUE;
15670 #endif
15671 /* Initialize default AFE configuartion for VSB */
15672 extAttr->vsbRfAgcCfg.standard = DRX_STANDARD_8VSB;
15673 extAttr->vsbRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15674 extAttr->vsbRfAgcCfg.minOutputLevel = 0;
15675 extAttr->vsbRfAgcCfg.maxOutputLevel = 0x7FFF;
15676 extAttr->vsbRfAgcCfg.speed = 3;
15677 extAttr->vsbRfAgcCfg.top = 9500;
15678 extAttr->vsbRfAgcCfg.cutOffCurrent = 4000;
15679 extAttr->vsbPreSawCfg.standard = DRX_STANDARD_8VSB;
15680 extAttr->vsbPreSawCfg.reference = 0x07;
15681 extAttr->vsbPreSawCfg.usePreSaw = TRUE;
15682
15683 #ifndef DRXJ_DIGITAL_ONLY
15684 /* Initialize default AFE configuartion for ATV */
15685 extAttr->atvRfAgcCfg.standard = DRX_STANDARD_NTSC;
15686 extAttr->atvRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15687 extAttr->atvRfAgcCfg.top = 9500;
15688 extAttr->atvRfAgcCfg.cutOffCurrent = 4000;
15689 extAttr->atvRfAgcCfg.speed = 3;
15690 extAttr->atvIfAgcCfg.standard = DRX_STANDARD_NTSC;
15691 extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
15692 extAttr->atvIfAgcCfg.speed = 3;
15693 extAttr->atvIfAgcCfg.top = 2400;
15694 extAttr->atvPreSawCfg.reference = 0x0007;
15695 extAttr->atvPreSawCfg.usePreSaw = TRUE;
15696 extAttr->atvPreSawCfg.standard = DRX_STANDARD_NTSC;
15697 #endif
15698 extAttr->standard = DRX_STANDARD_UNKNOWN;
15699
15700 CHK_ERROR(SmartAntInit(demod));
15701
15702 /* Stamp driver version number in SCU data RAM in BCD code
15703 Done to enable field application engineers to retreive drxdriver version
15704 via I2C from SCU RAM
15705 */
15706 driverVersion = (VERSION_MAJOR / 100) % 10;
15707 driverVersion <<= 4;
15708 driverVersion += (VERSION_MAJOR / 10) % 10;
15709 driverVersion <<= 4;
15710 driverVersion += (VERSION_MAJOR % 10);
15711 driverVersion <<= 4;
15712 driverVersion += (VERSION_MINOR % 10);
15713 driverVersion <<= 4;
15714 driverVersion += (VERSION_PATCH / 1000) % 10;
15715 driverVersion <<= 4;
15716 driverVersion += (VERSION_PATCH / 100) % 10;
15717 driverVersion <<= 4;
15718 driverVersion += (VERSION_PATCH / 10) % 10;
15719 driverVersion <<= 4;
15720 driverVersion += (VERSION_PATCH % 10);
15721 WR16(devAddr, SCU_RAM_DRIVER_VER_HI__A, (u16_t) (driverVersion >> 16));
15722 WR16(devAddr, SCU_RAM_DRIVER_VER_LO__A,
15723 (u16_t) (driverVersion & 0xFFFF));
15724
15725 /* refresh the audio data structure with default */
15726 extAttr->audData = DRXJDefaultAudData_g;
15727
15728 return (DRX_STS_OK);
15729 rw_error:
15730 commonAttr->isOpened = FALSE;
15731 return (DRX_STS_ERROR);
15732 }
15733
15734 /*============================================================================*/
15735 /**
15736 * \fn DRXJ_Close()
15737 * \brief Close the demod instance, power down the device
15738 * \return Status_t Return status.
15739 *
15740 */
15741 DRXStatus_t DRXJ_Close(pDRXDemodInstance_t demod)
15742 {
15743 pI2CDeviceAddr_t devAddr = NULL;
15744 pDRXJData_t extAttr = NULL;
15745 pDRXCommonAttr_t commonAttr = NULL;
15746 DRXPowerMode_t powerMode = DRX_POWER_UP;
15747
15748 commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
15749 devAddr = demod->myI2CDevAddr;
15750 extAttr = (pDRXJData_t) demod->myExtAttr;
15751
15752 /* power up */
15753 CHK_ERROR(CtrlPowerMode(demod, &powerMode));
15754
15755 if (demod->myTuner != NULL) {
15756 /* Check if bridge is used */
15757 if (commonAttr->tunerPortNr == 1) {
15758 Bool_t bridgeClosed = TRUE;
15759 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
15760 }
15761 CHK_ERROR(DRXBSP_TUNER_Close(demod->myTuner));
15762 if (commonAttr->tunerPortNr == 1) {
15763 Bool_t bridgeClosed = FALSE;
15764 CHK_ERROR(CtrlI2CBridge(demod, &bridgeClosed));
15765 }
15766 };
15767
15768 WR16(devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
15769 powerMode = DRX_POWER_DOWN;
15770 CHK_ERROR(CtrlPowerMode(demod, &powerMode));
15771
15772 return DRX_STS_OK;
15773 rw_error:
15774 return (DRX_STS_ERROR);
15775 }
15776
15777 /*============================================================================*/
15778 /**
15779 * \fn DRXJ_Ctrl()
15780 * \brief DRXJ specific control function
15781 * \return Status_t Return status.
15782 */
15783 DRXStatus_t
15784 DRXJ_Ctrl(pDRXDemodInstance_t demod, DRXCtrlIndex_t ctrl, void *ctrlData)
15785 {
15786 switch (ctrl) {
15787 /*======================================================================*/
15788 case DRX_CTRL_SET_CHANNEL:
15789 {
15790 return CtrlSetChannel(demod, (pDRXChannel_t) ctrlData);
15791 }
15792 break;
15793 /*======================================================================*/
15794 case DRX_CTRL_GET_CHANNEL:
15795 {
15796 return CtrlGetChannel(demod, (pDRXChannel_t) ctrlData);
15797 }
15798 break;
15799 /*======================================================================*/
15800 case DRX_CTRL_SIG_QUALITY:
15801 {
15802 return CtrlSigQuality(demod,
15803 (pDRXSigQuality_t) ctrlData);
15804 }
15805 break;
15806 /*======================================================================*/
15807 case DRX_CTRL_SIG_STRENGTH:
15808 {
15809 return CtrlSigStrength(demod, (pu16_t) ctrlData);
15810 }
15811 break;
15812 /*======================================================================*/
15813 case DRX_CTRL_CONSTEL:
15814 {
15815 return CtrlConstel(demod, (pDRXComplex_t) ctrlData);
15816 }
15817 break;
15818 /*======================================================================*/
15819 case DRX_CTRL_SET_CFG:
15820 {
15821 return CtrlSetCfg(demod, (pDRXCfg_t) ctrlData);
15822 }
15823 break;
15824 /*======================================================================*/
15825 case DRX_CTRL_GET_CFG:
15826 {
15827 return CtrlGetCfg(demod, (pDRXCfg_t) ctrlData);
15828 }
15829 break;
15830 /*======================================================================*/
15831 case DRX_CTRL_I2C_BRIDGE:
15832 {
15833 return CtrlI2CBridge(demod, (pBool_t) ctrlData);
15834 }
15835 break;
15836 /*======================================================================*/
15837 case DRX_CTRL_LOCK_STATUS:
15838 {
15839 return CtrlLockStatus(demod,
15840 (pDRXLockStatus_t) ctrlData);
15841 }
15842 break;
15843 /*======================================================================*/
15844 case DRX_CTRL_SET_STANDARD:
15845 {
15846 return CtrlSetStandard(demod,
15847 (pDRXStandard_t) ctrlData);
15848 }
15849 break;
15850 /*======================================================================*/
15851 case DRX_CTRL_GET_STANDARD:
15852 {
15853 return CtrlGetStandard(demod,
15854 (pDRXStandard_t) ctrlData);
15855 }
15856 break;
15857 /*======================================================================*/
15858 case DRX_CTRL_POWER_MODE:
15859 {
15860 return CtrlPowerMode(demod, (pDRXPowerMode_t) ctrlData);
15861 }
15862 break;
15863 /*======================================================================*/
15864 case DRX_CTRL_VERSION:
15865 {
15866 return CtrlVersion(demod,
15867 (pDRXVersionList_t *) ctrlData);
15868 }
15869 break;
15870 /*======================================================================*/
15871 case DRX_CTRL_PROBE_DEVICE:
15872 {
15873 return CtrlProbeDevice(demod);
15874 }
15875 break;
15876 /*======================================================================*/
15877 case DRX_CTRL_SET_OOB:
15878 {
15879 return CtrlSetOOB(demod, (pDRXOOB_t) ctrlData);
15880 }
15881 break;
15882 /*======================================================================*/
15883 case DRX_CTRL_GET_OOB:
15884 {
15885 return CtrlGetOOB(demod, (pDRXOOBStatus_t) ctrlData);
15886 }
15887 break;
15888 /*======================================================================*/
15889 case DRX_CTRL_SET_UIO_CFG:
15890 {
15891 return CtrlSetUIOCfg(demod, (pDRXUIOCfg_t) ctrlData);
15892 }
15893 break;
15894 /*======================================================================*/
15895 case DRX_CTRL_GET_UIO_CFG:
15896 {
15897 return CtrlGetUIOCfg(demod, (pDRXUIOCfg_t) ctrlData);
15898 }
15899 break;
15900 /*======================================================================*/
15901 case DRX_CTRL_UIO_READ:
15902 {
15903 return CtrlUIORead(demod, (pDRXUIOData_t) ctrlData);
15904 }
15905 break;
15906 /*======================================================================*/
15907 case DRX_CTRL_UIO_WRITE:
15908 {
15909 return CtrlUIOWrite(demod, (pDRXUIOData_t) ctrlData);
15910 }
15911 break;
15912 /*======================================================================*/
15913 case DRX_CTRL_AUD_SET_STANDARD:
15914 {
15915 return AUDCtrlSetStandard(demod,
15916 (pDRXAudStandard_t) ctrlData);
15917 }
15918 break;
15919 /*======================================================================*/
15920 case DRX_CTRL_AUD_GET_STANDARD:
15921 {
15922 return AUDCtrlGetStandard(demod,
15923 (pDRXAudStandard_t) ctrlData);
15924 }
15925 break;
15926 /*======================================================================*/
15927 case DRX_CTRL_AUD_GET_STATUS:
15928 {
15929 return AUDCtrlGetStatus(demod,
15930 (pDRXAudStatus_t) ctrlData);
15931 }
15932 break;
15933 /*======================================================================*/
15934 case DRX_CTRL_AUD_BEEP:
15935 {
15936 return AUDCtrlBeep(demod, (pDRXAudBeep_t) ctrlData);
15937 }
15938 break;
15939
15940 /*======================================================================*/
15941 case DRX_CTRL_I2C_READWRITE:
15942 {
15943 return CtrlI2CWriteRead(demod,
15944 (pDRXI2CData_t) ctrlData);
15945 }
15946 break;
15947 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
15948 case DRX_CTRL_LOAD_UCODE:
15949 {
15950 return CtrlUCodeUpload(demod,
15951 (pDRXUCodeInfo_t) ctrlData,
15952 UCODE_UPLOAD, FALSE);
15953 }
15954 break;
15955 case DRX_CTRL_VERIFY_UCODE:
15956 {
15957 return CtrlUCodeUpload(demod,
15958 (pDRXUCodeInfo_t) ctrlData,
15959 UCODE_VERIFY, FALSE);
15960 }
15961 break;
15962 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
15963 case DRX_CTRL_VALIDATE_UCODE:
15964 {
15965 return CtrlValidateUCode(demod);
15966 }
15967 break;
15968 default:
15969 return (DRX_STS_FUNC_NOT_AVAILABLE);
15970 }
15971 return (DRX_STS_OK);
15972 }
15973
15974 /* END OF FILE */
This page took 0.415931 seconds and 5 git commands to generate.