2 Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
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
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.
32 * \file $Id: drxj.c,v 1.637 2010/01/18 17:21:10 dingtao Exp $
34 * \brief DRXJ specific implementation of DRX driver
36 * \author Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
39 /*-----------------------------------------------------------------------------
41 ----------------------------------------------------------------------------*/
47 #include "drxj_options.h"
50 /*============================================================================*/
51 /*=== DEFINES ================================================================*/
52 /*============================================================================*/
55 * \brief Maximum u32_t value.
58 #define MAX_U32 ((u32_t) (0xFFFFFFFFL))
61 /* Customer configurable hardware settings, etc */
62 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
63 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
66 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
67 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
70 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
71 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
74 #ifndef OOB_CRX_DRIVE_STRENGTH
75 #define OOB_CRX_DRIVE_STRENGTH 0x02
78 #ifndef OOB_DRX_DRIVE_STRENGTH
79 #define OOB_DRX_DRIVE_STRENGTH 0x02
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 *********************************/
171 #include "drx_driver_version.h"
178 /*-----------------------------------------------------------------------------
180 ----------------------------------------------------------------------------*/
182 /*-----------------------------------------------------------------------------
184 ----------------------------------------------------------------------------*/
185 #ifndef DRXJ_WAKE_UP_KEY
186 #define DRXJ_WAKE_UP_KEY (demod -> myI2CDevAddr -> i2cAddr)
190 * \def DRXJ_DEF_I2C_ADDR
191 * \brief Default I2C addres of a demodulator instance.
193 #define DRXJ_DEF_I2C_ADDR (0x52)
196 * \def DRXJ_DEF_DEMOD_DEV_ID
197 * \brief Default device identifier of a demodultor instance.
199 #define DRXJ_DEF_DEMOD_DEV_ID (1)
202 * \def DRXJ_SCAN_TIMEOUT
203 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
205 #define DRXJ_SCAN_TIMEOUT 1000
209 * \brief Name of structure containing all data access protocol functions.
211 #define DRXJ_DAP drxDapDRXJFunct_g
215 * \brief HI timing delay for I2C timing (in nano seconds)
217 * Used to compute HI_CFG_DIV
219 #define HI_I2C_DELAY 42
222 * \def HI_I2C_BRIDGE_DELAY
223 * \brief HI timing delay for I2C timing (in nano seconds)
225 * Used to compute HI_CFG_BDL
227 #define HI_I2C_BRIDGE_DELAY 750
230 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
232 #define VSB_TOP_MEASUREMENT_PERIOD 64
233 #define SYMBOLS_PER_SEGMENT 832
236 * \brief bit rate and segment rate constants used for SER and BER.
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
248 * \brief Min supported symbolrates.
250 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
251 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
255 * \brief Max supported symbolrates.
257 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
258 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
262 * \def DRXJ_QAM_MAX_WAITTIME
263 * \brief Maximal wait time for QAM auto constellation in ms
265 #ifndef DRXJ_QAM_MAX_WAITTIME
266 #define DRXJ_QAM_MAX_WAITTIME 900
269 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
270 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
273 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
274 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
278 * \def SCU status and results
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 */
287 * \def DRX_AUD_MAX_DEVIATION
288 * \brief Needed for calculation of prescale feature in AUD
290 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
291 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
295 * \brief Needed for calculation of NICAM prescale feature in AUD
297 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
298 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
302 * \brief Needed for calculation of NICAM prescale feature in AUD
304 #ifndef DRXJ_AUD_MAX_WAITTIME
305 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
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 )
316 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
317 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
319 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
320 /*============================================================================*/
321 /*=== MICROCODE RELATED DEFINES ==============================================*/
322 /*============================================================================*/
325 * \def DRXJ_UCODE_MAGIC_WORD
326 * \brief Magic word for checking correct Endianess of microcode data.
330 #ifndef DRXJ_UCODE_MAGIC_WORD
331 #define DRXJ_UCODE_MAGIC_WORD ((((u16_t)'H')<<8)+((u16_t)'L'))
335 * \def DRXJ_UCODE_CRC_FLAG
336 * \brief CRC flag in ucode header, flags field.
340 #ifndef DRXJ_UCODE_CRC_FLAG
341 #define DRXJ_UCODE_CRC_FLAG (0x0001)
345 * \def DRXJ_UCODE_COMPRESSION_FLAG
346 * \brief Compression flag in ucode header, flags field.
350 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
351 #define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
355 * \def DRXJ_UCODE_MAX_BUF_SIZE
356 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
360 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
361 #define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
363 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
364 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
367 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
369 /* Pin safe mode macro */
370 #define DRXJ_PIN_SAFE_MODE 0x0000
371 /*============================================================================*/
372 /*=== GLOBAL VARIABLEs =======================================================*/
373 /*============================================================================*/
378 * \brief Temporary register definitions.
379 * (register definitions that are not yet available in register master)
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 */
387 /******************************************************************************/
389 * \brief RAM location of MODUS registers
391 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
392 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
394 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
395 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
398 * \brief RAM location of I2S config registers
400 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
401 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
404 * \brief RAM location of DCO config registers
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
412 * \brief RAM location of Threshold registers
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
419 * \brief RAM location of Carrier Threshold registers
421 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
422 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
425 * \brief FM Matrix register fix
427 #ifdef AUD_DEM_WR_FM_MATRIX__A
428 #undef AUD_DEM_WR_FM_MATRIX__A
430 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
432 /*============================================================================*/
434 * \brief Defines required for audio
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
447 * \brief Needed for calculation of prescale feature in AUD
449 #ifndef DRX_AUD_MAX_FM_DEVIATION
450 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
454 * \brief Needed for calculation of NICAM prescale feature in AUD
456 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
457 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
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
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
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
477 /*============================================================================*/
478 /*=== REGISTER ACCESS MACROS =================================================*/
479 /*============================================================================*/
481 #ifdef DRXJDRIVER_DEBUG
483 #define CHK_ERROR( s ) \
485 if ( (s) != DRX_STS_OK ) \
488 "ERROR[\n file : %s\n line : %d\n]\n", \
489 __FILE__,__LINE__); \
494 #define CHK_ERROR( s ) \
496 if ( (s) != DRX_STS_OK ) { goto rw_error; } \
500 #define CHK_ZERO( s ) \
502 if ( (s) == 0 ) return DRX_STS_ERROR; \
505 #define DUMMY_READ() \
508 RR16( demod->myI2CDevAddr, SCU_RAM_VERSION_HI__A, &dummy ); \
511 #define WR16( dev, addr, val) \
512 CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), 0 ) )
514 #define RR16( dev, addr, val) \
515 CHK_ERROR( DRXJ_DAP.readReg16Func( (dev), (addr), (val), 0 ) )
517 #define WR32( dev, addr, val) \
518 CHK_ERROR( DRXJ_DAP.writeReg32Func( (dev), (addr), (val), 0 ) )
520 #define RR32( dev, addr, val) \
521 CHK_ERROR( DRXJ_DAP.readReg32Func( (dev), (addr), (val), 0 ) )
523 #define WRB( dev, addr, len, block ) \
524 CHK_ERROR( DRXJ_DAP.writeBlockFunc( (dev), (addr), (len), (block), 0 ) )
526 #define RRB( dev, addr, len, block ) \
527 CHK_ERROR( DRXJ_DAP.readBlockFunc( (dev), (addr), (len), (block), 0 ) )
529 #define BCWR16( dev, addr, val ) \
530 CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), DRXDAP_FASI_BROADCAST ) )
532 #define ARR32( dev, addr, val) \
533 CHK_ERROR( DRXJ_DAP_AtomicReadReg32( (dev), (addr), (val), 0 ) )
535 #define SARR16( dev, addr, val) \
536 CHK_ERROR( DRXJ_DAP_SCU_AtomicReadReg16( (dev), (addr), (val), 0 ) )
538 #define SAWR16( dev, addr, val) \
539 CHK_ERROR( DRXJ_DAP_SCU_AtomicWriteReg16( (dev), (addr), (val), 0 ) )
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)
547 #define DRXJ_16TO8( x ) ((u8_t) (((u16_t)x) &0xFF)), \
548 ((u8_t)((((u16_t)x)>>8)&0xFF))
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.
554 #define DRXJ_8TO16( x ) ((u16_t) (x[0] | (x[1] << 8)))
556 /*============================================================================*/
557 /*=== MISC DEFINES ===========================================================*/
558 /*============================================================================*/
560 /*============================================================================*/
561 /*=== HI COMMAND RELATED DEFINES =============================================*/
562 /*============================================================================*/
565 * \brief General maximum number of retries for ucode command interfaces
567 #define DRXJ_MAX_RETRIES (100)
569 /*============================================================================*/
570 /*=== STANDARD RELATED MACROS ================================================*/
571 /*============================================================================*/
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 ) )
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 ))
586 /*-----------------------------------------------------------------------------
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
);
594 /*-----------------------------------------------------------------------------
596 ----------------------------------------------------------------------------*/
598 * DRXJ DAP structures
601 static DRXStatus_t
DRXJ_DAP_ReadBlock(pI2CDeviceAddr_t devAddr
,
604 pu8_t data
, DRXflags_t flags
);
606 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg8(pI2CDeviceAddr_t devAddr
,
609 u8_t wdata
, pu8_t rdata
);
611 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg16(pI2CDeviceAddr_t devAddr
,
614 u16_t wdata
, pu16_t rdata
);
616 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg32(pI2CDeviceAddr_t devAddr
,
619 u32_t wdata
, pu32_t rdata
);
621 static DRXStatus_t
DRXJ_DAP_ReadReg8(pI2CDeviceAddr_t devAddr
,
623 pu8_t data
, DRXflags_t flags
);
625 static DRXStatus_t
DRXJ_DAP_ReadReg16(pI2CDeviceAddr_t devAddr
,
627 pu16_t data
, DRXflags_t flags
);
629 static DRXStatus_t
DRXJ_DAP_ReadReg32(pI2CDeviceAddr_t devAddr
,
631 pu32_t data
, DRXflags_t flags
);
633 static DRXStatus_t
DRXJ_DAP_WriteBlock(pI2CDeviceAddr_t devAddr
,
636 pu8_t data
, DRXflags_t flags
);
638 static DRXStatus_t
DRXJ_DAP_WriteReg8(pI2CDeviceAddr_t devAddr
,
640 u8_t data
, DRXflags_t flags
);
642 static DRXStatus_t
DRXJ_DAP_WriteReg16(pI2CDeviceAddr_t devAddr
,
644 u16_t data
, DRXflags_t flags
);
646 static DRXStatus_t
DRXJ_DAP_WriteReg32(pI2CDeviceAddr_t devAddr
,
648 u32_t data
, DRXflags_t flags
);
650 /* The version structure of this protocol implementation */
651 char drxDapDRXJModuleName
[] = "DRXJ Data Access Protocol";
652 char drxDapDRXJVersionText
[] = "0.0.0";
654 DRXVersion_t drxDapDRXJVersion
= {
655 DRX_MODULE_DAP
, /**< type identifier of the module */
656 drxDapDRXJModuleName
, /**< name or description of module */
658 0, /**< major version number */
659 0, /**< minor version number */
660 0, /**< patch version number */
661 drxDapDRXJVersionText
/**< version as text string */
664 /* The structure containing the protocol interface */
665 DRXAccessFunc_t drxDapDRXJFunct_g
= {
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 */
682 * /brief The driver functions of the drxj
684 DRXDemodFunc_t DRXJFunctions_g
= {
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... */
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 */
711 /* signal quality information: */
712 /* default values taken from the QAM Programming guide */
713 /* fecBitsDesired should not be less than 4000000 */
714 4000000, /* fecBitsDesired */
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 */
724 /* HI configuration */
725 0, /* HICfgTimingDiv */
726 0, /* HICfgBridgeDelay */
727 0, /* HICfgWakeUpKey */
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 */
736 0UL, /* iqmFsRateOfs */
737 FALSE
, /* posImage */
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 */
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 */
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 */
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 */
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 */
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 */
792 DRX_STANDARD_ITU_B
, /* standard */
793 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
795 0, /* minOutputLevel */
796 0xFFFF, /* maxOutputLevel */
802 DRX_STANDARD_ITU_B
, /* standard */
803 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
805 0, /* minOutputLevel */
806 0xFFFF, /* maxOutputLevel */
808 0x0000, /* top (don't care) */
809 0x0000 /* c.o.c. (don't care) */
812 DRX_STANDARD_8VSB
, /* standard */
813 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
815 0, /* minOutputLevel */
816 0xFFFF, /* maxOutputLevel */
818 0x0000, /* top (don't care) */
819 0x0000 /* c.o.c. (don't care) */
822 DRX_STANDARD_8VSB
, /* standard */
823 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
825 0, /* minOutputLevel */
826 0xFFFF, /* maxOutputLevel */
828 0x0000, /* top (don't care) */
829 0x0000 /* c.o.c. (don't care) */
834 DRX_STANDARD_ITU_B
, /* standard */
836 FALSE
/* usePreSaw */
839 DRX_STANDARD_8VSB
, /* standard */
841 FALSE
/* usePreSaw */
844 /* Version information */
847 "01234567890", /* human readable version microcode */
848 "01234567890" /* human readable version device specific code */
851 { /* DRXVersion_t for microcode */
859 { /* DRXVersion_t for device specific code */
869 { /* DRXVersionList_t for microcode */
870 (pDRXVersion_t
) (NULL
),
871 (pDRXVersionList_t
) (NULL
)
873 { /* DRXVersionList_t for device specific code */
874 (pDRXVersion_t
) (NULL
),
875 (pDRXVersionList_t
) (NULL
)
879 FALSE
, /* smartAntInverted */
880 /* Tracking filter setting for OOB */
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 */
897 /* Pre SAW & Agc configuration for ATV */
899 DRX_STANDARD_NTSC
, /* standard */
904 DRX_STANDARD_NTSC
, /* standard */
905 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
907 0, /* minOutputLevel (d.c.) */
908 0, /* maxOutputLevel (d.c.) */
911 4000 /* cut-off current */
914 DRX_STANDARD_NTSC
, /* standard */
915 DRX_AGC_CTRL_AUTO
, /* ctrlMode */
917 0, /* minOutputLevel (d.c.) */
918 0, /* maxOutputLevel (d.c.) */
921 0 /* c.o.c. (d.c.) */
923 140, /* ATV PGA config */
924 0, /* currSymbolRate */
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 */
933 DRXJ_OOB_LO_POW_MINUS10DB
, /* oobLoPow */
935 FALSE
/* audData, only first member */
940 * \var DRXJDefaultAddr_g
941 * \brief Default I2C address and device identifier.
943 I2CDeviceAddr_t DRXJDefaultAddr_g
= {
944 DRXJ_DEF_I2C_ADDR
, /* i2c address */
945 DRXJ_DEF_DEMOD_DEV_ID
/* device id */
949 * \var DRXJDefaultCommAttr_g
950 * \brief Default common attributes of a drxj demodulator instance.
952 DRXCommonAttr_t DRXJDefaultCommAttr_g
= {
953 (pu8_t
) NULL
, /* ucode ptr */
955 TRUE
, /* ucode verify switch */
956 {0}, /* version record */
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 */
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 */
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 */
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 */
998 /* Power management */
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 */
1009 { /* current channel (all 0) */
1010 0UL /* channel.frequency */
1012 DRX_STANDARD_UNKNOWN
, /* current standard */
1013 DRX_STANDARD_UNKNOWN
, /* previous standard */
1014 DRX_STANDARD_UNKNOWN
, /* diCacheStandard */
1015 FALSE
, /* useBootloader */
1016 0UL, /* capabilities */
1021 * \var DRXJDefaultDemod_g
1022 * \brief Default drxj demodulator instance.
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 */
1034 * \brief Default audio data structure for DRK demodulator instance.
1036 * This structure is DRXK specific.
1039 DRXAudData_t DRXJDefaultAudData_g
= {
1040 FALSE
, /* audioIsActive */
1041 DRX_AUD_STANDARD_AUTO
, /* audioStandard */
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 */
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 */
1063 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON
, /* autoSound */
1075 DRX_NO_CARRIER_NOISE
, /* opt */
1082 DRX_NO_CARRIER_MUTE
, /* opt */
1090 DRX_AUD_SRC_STEREO_OR_A
, /* sourceI2S */
1091 DRX_AUD_I2S_MATRIX_STEREO
, /* matrixI2S */
1092 DRX_AUD_FM_MATRIX_SOUND_A
/* matrixFm */
1094 DRX_AUD_DEVIATION_NORMAL
, /* deviation */
1095 DRX_AUD_AVSYNC_OFF
, /* avSync */
1099 DRX_AUD_MAX_FM_DEVIATION
, /* fmDeviation */
1100 DRX_AUD_MAX_NICAM_PRESCALE
/* nicamGain */
1102 DRX_AUD_FM_DEEMPH_75US
, /* deemph */
1103 DRX_BTSC_STEREO
, /* btscDetect */
1104 0, /* rdsDataCounter */
1105 FALSE
/* rdsDataPresent */
1108 /*-----------------------------------------------------------------------------
1110 ----------------------------------------------------------------------------*/
1116 } DRXJEQStat_t
, *pDRXJEQStat_t
;
1127 } DRXJHiCmd_t
, *pDRXJHiCmd_t
;
1129 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1130 /*============================================================================*/
1131 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1132 /*============================================================================*/
1137 u16_t flags
; /* bit[15..2]=reserved,
1138 bit[1]= compression on/off
1139 bit[0]= CRC on/off */
1141 } DRXUCodeBlockHdr_t
, *pDRXUCodeBlockHdr_t
;
1142 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1144 /*-----------------------------------------------------------------------------
1146 ----------------------------------------------------------------------------*/
1147 /* Some prototypes */
1149 HICommand(const pI2CDeviceAddr_t devAddr
,
1150 const pDRXJHiCmd_t cmd
, pu16_t result
);
1153 CtrlLockStatus(pDRXDemodInstance_t demod
, pDRXLockStatus_t lockStat
);
1156 CtrlPowerMode(pDRXDemodInstance_t demod
, pDRXPowerMode_t mode
);
1158 static DRXStatus_t
PowerDownAud(pDRXDemodInstance_t demod
);
1160 #ifndef DRXJ_DIGITAL_ONLY
1161 static DRXStatus_t
PowerUpAud(pDRXDemodInstance_t demod
, Bool_t setStandard
);
1165 AUDCtrlSetStandard(pDRXDemodInstance_t demod
, pDRXAudStandard_t standard
);
1168 CtrlSetCfgPreSaw(pDRXDemodInstance_t demod
, pDRXJCfgPreSaw_t preSaw
);
1171 CtrlSetCfgAfeGain(pDRXDemodInstance_t demod
, pDRXJCfgAfeGain_t afeGain
);
1173 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1175 CtrlUCodeUpload(pDRXDemodInstance_t demod
,
1176 pDRXUCodeInfo_t mcInfo
,
1177 DRXUCodeAction_t action
, Bool_t audioMCUpload
);
1178 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1180 /*============================================================================*/
1181 /*============================================================================*/
1182 /*== HELPER FUNCTIONS ==*/
1183 /*============================================================================*/
1184 /*============================================================================*/
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
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.
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.
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.
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
1222 * Note that the function is type size independent. Any unsigned integer type
1223 * can be substituted for booth_t.
1227 #define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof (u32_t) * 8 - 1))) != 0)
1229 static void Mult32(u32_t a
, u32_t b
, pu32_t h
, pu32_t l
)
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));
1241 /* Take the first three bits of operand a for the Booth conversion: */
1242 /* 0, 7: do nothing */
1245 /* 4 : subtract 2b */
1246 /* 5, 6: subtract b */
1247 switch (a
>> (sizeof(a
) * 8 - 3)) {
1250 *h
= *h
- DRX_IS_BOOTH_NEGATIVE(b
) + (*l
< b
);
1254 *h
= *h
- DRX_IS_BOOTH_NEGATIVE(b
) + (*l
< b
);
1258 *h
= *h
- !DRX_IS_BOOTH_NEGATIVE(b
) + !b
+ (*l
<
1266 *h
= *h
- !DRX_IS_BOOTH_NEGATIVE(b
) + !b
+ (*l
<
1276 /*============================================================================*/
1279 * \fn u32_t Frac28(u32_t N, u32_t D)
1280 * \brief Compute: (1<<28)*N/D
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.
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.
1292 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1294 * N: 0...(1<<28)-1 = 268435454
1298 static u32_t
Frac28(u32_t N
, u32_t D
)
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 */
1308 /* division using radix 16, 7 nibbles in the result */
1309 for (i
= 0; i
< 7; i
++) {
1310 Q1
= (Q1
<< 4) | R0
/ D
;
1321 * \fn u32_t Log10Times100( u32_t x)
1322 * \brief Compute: 100*log10(x)
1324 * \return 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
1333 * where y = 2^k and 1<= (x/y) < 2
1336 static u32_t
Log10Times100(u32_t x
)
1338 static const u8_t scale
= 15;
1339 static const u8_t indexWidth
= 5;
1341 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1342 0 <= n < ((1<<INDEXWIDTH)+1)
1345 static const u32_t log2lut
[] = {
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 */
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
))
1399 for (k
= scale
; k
< 31; k
++) {
1400 if ((x
& (((u32_t
) (-1)) << (scale
+ 1))) == 0)
1406 Now x has binary point between bit[scale] and bit[scale-1]
1407 and 1.0 <= x < 2.0 */
1409 /* correction for divison: log(x) = log(x/y)+log(y) */
1410 y
= k
* ((((u32_t
) 1) << scale
) * 200);
1412 /* remove integer part */
1413 x
&= ((((u32_t
) 1) << scale
) - 1);
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 ! */
1420 ((d
* (log2lut
[i
+ 1] - log2lut
[i
])) >> (scale
- indexWidth
));
1421 /* Conver to log10() */
1422 y
/= 108853; /* (log2(10) << scale) */
1425 if (y
& ((u32_t
) 1))
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.
1438 * \retval ((N/D) * 1000000), 32 bits
1442 static u32_t
FracTimes1e6(u32_t N
, u32_t D
)
1444 u32_t remainder
= 0;
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.
1454 frac
= (((u32_t
) N
) * (1000000 >> 4)) / D
;
1456 remainder
= (((u32_t
) N
) * (1000000 >> 4)) % D
;
1458 frac
+= remainder
/ D
;
1459 remainder
= remainder
% D
;
1460 if ((remainder
* 2) > D
) {
1467 /*============================================================================*/
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
1475 static u32_t
dB2LinTimes100(u32_t GdB
)
1478 u32_t nr6dBSteps
= 0;
1479 u32_t remainder
= 0;
1480 u32_t remainderFac
= 0;
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 */
1488 result
= (1 << nr6dBSteps
);
1490 /* calculate remaining factor,
1491 poly approximation of 10^(GdB/200):
1493 y = 1E-04x2 + 0.0106x + 1.0026
1495 max deviation < 0.005 for range x = [0 ... 60]
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;
1503 /* multiply by remaining factor */
1504 result
*= remainderFac
;
1506 /* conversion from 1e-4 to 1e-2 */
1507 return ((result
+ 50) / 100);
1510 #ifndef DRXJ_DIGITAL_ONLY
1511 #define FRAC_FLOOR 0
1513 #define FRAC_ROUND 2
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
1521 * \retval N/D, 32 bits
1525 static u32_t
Frac(u32_t N
, u32_t D
, u16_t RC
)
1527 u32_t remainder
= 0;
1544 while (bitCnt
-- > 0) {
1546 remainder
|= ((frac
& 0x80000000) >> 31);
1548 if (remainder
< D
) {
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) */
1562 if ((RC
== FRAC_ROUND
) && (remainder
>= D
>> 1)) {
1563 /* remainder is bigger from D/2 -> round the result */
1572 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1573 /*============================================================================*/
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.
1580 static u16_t
UCodeRead16(pu8_t addr
)
1582 /* Works fo any host processor */
1586 word
= ((u16_t
) addr
[0]);
1588 word
|= ((u16_t
) addr
[1]);
1593 /*============================================================================*/
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.
1600 static u32_t
UCodeRead32(pu8_t addr
)
1602 /* Works fo any host processor */
1606 word
= ((u16_t
) addr
[0]);
1608 word
|= ((u16_t
) addr
[1]);
1610 word
|= ((u16_t
) addr
[2]);
1612 word
|= ((u16_t
) addr
[3]);
1617 /*============================================================================*/
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.
1626 static u16_t
UCodeComputeCRC(pu8_t blockData
, u16_t nrWords
)
1633 while (i
< nrWords
) {
1634 CRCWord
|= (u32_t
) UCodeRead16(blockData
);
1635 for (j
= 0; j
< 16; j
++) {
1638 CRCWord
^= 0x80050000UL
;
1639 carry
= CRCWord
& 0x80000000UL
;
1642 blockData
+= (sizeof(u16_t
));
1644 return ((u16_t
) (CRCWord
>> 16));
1646 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1649 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1650 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
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
1660 /*============================================================================*/
1661 /*== END HELPER FUNCTIONS ==*/
1662 /*============================================================================*/
1664 /*============================================================================*/
1665 /*============================================================================*/
1666 /*== DRXJ DAP FUNCTIONS ==*/
1667 /*============================================================================*/
1668 /*============================================================================*/
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.
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.
1683 TODO: check ignoring single/multimaster is ok for AUD access ?
1686 #define DRXJ_ISAUDWRITE( addr ) (((((addr)>>16)&1)==1)?TRUE:FALSE)
1687 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1688 /*============================================================================*/
1691 * \fn Bool_t IsHandledByAudTrIf( DRXaddr_t addr )
1692 * \brief Check if this address is handled by the audio token ring interface.
1695 * \retval TRUE Yes, handled by audio token ring interface
1696 * \retval FALSE No, not handled by audio token ring interface
1700 Bool_t
IsHandledByAudTrIf(DRXaddr_t addr
)
1702 Bool_t retval
= FALSE
;
1704 if ((DRXDAP_FASI_ADDR2BLOCK(addr
) == 4) &&
1705 (DRXDAP_FASI_ADDR2BANK(addr
) > 1) &&
1706 (DRXDAP_FASI_ADDR2BANK(addr
) < 6)) {
1713 /*============================================================================*/
1715 static DRXStatus_t
DRXJ_DAP_ReadBlock(pI2CDeviceAddr_t devAddr
,
1718 pu8_t data
, DRXflags_t flags
)
1720 return drxDapFASIFunct_g
.readBlockFunc(devAddr
,
1721 addr
, datasize
, data
, flags
);
1724 /*============================================================================*/
1726 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg8(pI2CDeviceAddr_t devAddr
,
1729 u8_t wdata
, pu8_t rdata
)
1731 return drxDapFASIFunct_g
.readModifyWriteReg8Func(devAddr
,
1733 raddr
, wdata
, rdata
);
1736 /*============================================================================*/
1739 * \fn DRXStatus_t DRXJ_DAP_RMWriteReg16Short
1740 * \brief Read modify write 16 bits audio register using short format only.
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
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.
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
,
1762 u16_t wdata
, pu16_t rdata
)
1766 if (rdata
== NULL
) {
1767 return DRX_STS_INVALID_ARG
;
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
,
1775 if (rc
== DRX_STS_OK
) {
1776 /* Write new data: triggers RMW */
1777 rc
= drxDapFASIFunct_g
.writeReg16Func(devAddr
, waddr
, wdata
,
1780 if (rc
== DRX_STS_OK
) {
1782 rc
= drxDapFASIFunct_g
.readReg16Func(devAddr
, raddr
, rdata
,
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
,
1796 /*============================================================================*/
1798 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg16(pI2CDeviceAddr_t devAddr
,
1801 u16_t wdata
, pu16_t rdata
)
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
,
1809 raddr
, wdata
, rdata
);
1811 return DRXJ_DAP_RMWriteReg16Short(devAddr
, waddr
, raddr
, wdata
, rdata
);
1815 /*============================================================================*/
1817 static DRXStatus_t
DRXJ_DAP_ReadModifyWriteReg32(pI2CDeviceAddr_t devAddr
,
1820 u32_t wdata
, pu32_t rdata
)
1822 return drxDapFASIFunct_g
.readModifyWriteReg32Func(devAddr
,
1824 raddr
, wdata
, rdata
);
1827 /*============================================================================*/
1829 static DRXStatus_t
DRXJ_DAP_ReadReg8(pI2CDeviceAddr_t devAddr
,
1831 pu8_t data
, DRXflags_t flags
)
1833 return drxDapFASIFunct_g
.readReg8Func(devAddr
, addr
, data
, flags
);
1836 /*============================================================================*/
1839 * \fn DRXStatus_t DRXJ_DAP_ReadAudReg16
1840 * \brief Read 16 bits audio register
1844 * \return DRXStatus_t
1845 * \retval DRX_STS_OK Succes
1846 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1848 * 16 bits register read access via audio token ring interface.
1851 static DRXStatus_t
DRXJ_DAP_ReadAudReg16(pI2CDeviceAddr_t devAddr
,
1852 DRXaddr_t addr
, pu16_t data
)
1854 u32_t startTimer
= 0;
1855 u32_t currentTimer
= 0;
1856 u32_t deltaTimer
= 0;
1858 DRXStatus_t stat
= DRX_STS_ERROR
;
1860 /* No read possible for bank 3, return with error */
1861 if (DRXDAP_FASI_ADDR2BANK(addr
) == 3) {
1862 stat
= DRX_STS_INVALID_ARG
;
1864 const DRXaddr_t writeBit
= ((DRXaddr_t
) 1) << 16;
1866 /* Force reset write bit */
1867 addr
&= (~writeBit
);
1870 startTimer
= DRXBSP_HST_Clock();
1872 /* RMW to aud TR IF until request is granted or timeout */
1873 stat
= DRXJ_DAP_ReadModifyWriteReg16(devAddr
,
1875 SIO_HI_RA_RAM_S0_RMWBUF__A
,
1878 if (stat
!= DRX_STS_OK
) {
1882 currentTimer
= DRXBSP_HST_Clock();
1883 deltaTimer
= currentTimer
- startTimer
;
1884 if (deltaTimer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
1885 stat
= DRX_STS_ERROR
;
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 ) */
1895 /* Wait for read ready status or timeout */
1896 if (stat
== DRX_STS_OK
) {
1897 startTimer
= DRXBSP_HST_Clock();
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
,
1904 if (stat
!= DRX_STS_OK
) {
1908 currentTimer
= DRXBSP_HST_Clock();
1909 deltaTimer
= currentTimer
- startTimer
;
1910 if (deltaTimer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
1911 stat
= DRX_STS_ERROR
;
1914 } /* while ( ... ) */
1917 /* if { stat == DRX_STS_OK ) */
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
,
1925 /* if { stat == DRX_STS_OK ) */
1929 /*============================================================================*/
1931 static DRXStatus_t
DRXJ_DAP_ReadReg16(pI2CDeviceAddr_t devAddr
,
1933 pu16_t data
, DRXflags_t flags
)
1935 DRXStatus_t stat
= DRX_STS_ERROR
;
1938 if ((devAddr
== NULL
) || (data
== NULL
)) {
1939 return DRX_STS_INVALID_ARG
;
1942 if (IsHandledByAudTrIf(addr
)) {
1943 stat
= DRXJ_DAP_ReadAudReg16(devAddr
, addr
, data
);
1945 stat
= drxDapFASIFunct_g
.readReg16Func(devAddr
,
1952 /*============================================================================*/
1954 static DRXStatus_t
DRXJ_DAP_ReadReg32(pI2CDeviceAddr_t devAddr
,
1956 pu32_t data
, DRXflags_t flags
)
1958 return drxDapFASIFunct_g
.readReg32Func(devAddr
, addr
, data
, flags
);
1961 /*============================================================================*/
1963 static DRXStatus_t
DRXJ_DAP_WriteBlock(pI2CDeviceAddr_t devAddr
,
1966 pu8_t data
, DRXflags_t flags
)
1968 return drxDapFASIFunct_g
.writeBlockFunc(devAddr
,
1969 addr
, datasize
, data
, flags
);
1972 /*============================================================================*/
1974 static DRXStatus_t
DRXJ_DAP_WriteReg8(pI2CDeviceAddr_t devAddr
,
1976 u8_t data
, DRXflags_t flags
)
1978 return drxDapFASIFunct_g
.writeReg8Func(devAddr
, addr
, data
, flags
);
1981 /*============================================================================*/
1984 * \fn DRXStatus_t DRXJ_DAP_WriteAudReg16
1985 * \brief Write 16 bits audio register
1989 * \return DRXStatus_t
1990 * \retval DRX_STS_OK Succes
1991 * \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1993 * 16 bits register write access via audio token ring interface.
1996 static DRXStatus_t
DRXJ_DAP_WriteAudReg16(pI2CDeviceAddr_t devAddr
,
1997 DRXaddr_t addr
, u16_t data
)
1999 DRXStatus_t stat
= DRX_STS_ERROR
;
2001 /* No write possible for bank 2, return with error */
2002 if (DRXDAP_FASI_ADDR2BANK(addr
) == 2) {
2003 stat
= DRX_STS_INVALID_ARG
;
2005 u32_t startTimer
= 0;
2006 u32_t currentTimer
= 0;
2007 u32_t deltaTimer
= 0;
2009 const DRXaddr_t writeBit
= ((DRXaddr_t
) 1) << 16;
2011 /* Force write bit */
2013 startTimer
= DRXBSP_HST_Clock();
2015 /* RMW to aud TR IF until request is granted or timeout */
2016 stat
= DRXJ_DAP_ReadModifyWriteReg16(devAddr
,
2018 SIO_HI_RA_RAM_S0_RMWBUF__A
,
2020 if (stat
!= DRX_STS_OK
) {
2024 currentTimer
= DRXBSP_HST_Clock();
2025 deltaTimer
= currentTimer
- startTimer
;
2026 if (deltaTimer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
2027 stat
= DRX_STS_ERROR
;
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
));
2036 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2041 /*============================================================================*/
2043 static DRXStatus_t
DRXJ_DAP_WriteReg16(pI2CDeviceAddr_t devAddr
,
2045 u16_t data
, DRXflags_t flags
)
2047 DRXStatus_t stat
= DRX_STS_ERROR
;
2050 if (devAddr
== NULL
) {
2051 return DRX_STS_INVALID_ARG
;
2054 if (IsHandledByAudTrIf(addr
)) {
2055 stat
= DRXJ_DAP_WriteAudReg16(devAddr
, addr
, data
);
2057 stat
= drxDapFASIFunct_g
.writeReg16Func(devAddr
,
2064 /*============================================================================*/
2066 static DRXStatus_t
DRXJ_DAP_WriteReg32(pI2CDeviceAddr_t devAddr
,
2068 u32_t data
, DRXflags_t flags
)
2070 return drxDapFASIFunct_g
.writeReg32Func(devAddr
, addr
, data
, flags
);
2073 /*============================================================================*/
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
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
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
2097 DRXStatus_t
DRXJ_DAP_AtomicReadWriteBlock(pI2CDeviceAddr_t devAddr
,
2100 pu8_t data
, Bool_t readFlag
)
2108 /* Parameter check */
2109 if ((data
== NULL
) ||
2110 (devAddr
== NULL
) || ((datasize
% 2) != 0) || ((datasize
/ 2) > 8)
2112 return (DRX_STS_INVALID_ARG
);
2115 /* Set up HI parameters to read or write n bytes */
2116 hiCmd
.cmd
= SIO_HI_RA_RAM_CMD_ATOMIC_COPY
;
2118 (u16_t
) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START
) << 6) +
2119 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START
));
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
;
2126 hiCmd
.param3
|= DRXJ_HI_ATOMIC_READ
;
2128 hiCmd
.param4
= (u16_t
) ((DRXDAP_FASI_ADDR2BLOCK(addr
) << 6) +
2129 DRXDAP_FASI_ADDR2BANK(addr
));
2130 hiCmd
.param5
= (u16_t
) DRXDAP_FASI_ADDR2OFFSET(addr
);
2132 if (readFlag
== FALSE
) {
2133 /* write data to buffer */
2134 for (i
= 0; i
< (datasize
/ 2); i
++) {
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
),
2144 CHK_ERROR(HICommand(devAddr
, &hiCmd
, &dummy
));
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
),
2152 data
[2 * i
] = (u8_t
) (word
& 0xFF);
2153 data
[(2 * i
) + 1] = (u8_t
) (word
>> 8);
2160 return (DRX_STS_ERROR
);
2164 /*============================================================================*/
2167 * \fn DRXStatus_t DRXJ_DAP_AtomicReadReg32()
2168 * \brief Atomic read of 32 bits words
2171 DRXStatus_t
DRXJ_DAP_AtomicReadReg32(pI2CDeviceAddr_t devAddr
,
2173 pu32_t data
, DRXflags_t flags
)
2175 u8_t buf
[sizeof(*data
)];
2176 DRXStatus_t rc
= DRX_STS_ERROR
;
2180 return DRX_STS_INVALID_ARG
;
2183 rc
= DRXJ_DAP_AtomicReadWriteBlock(devAddr
, addr
,
2184 sizeof(*data
), buf
, TRUE
);
2186 word
= (u32_t
) buf
[3];
2188 word
|= (u32_t
) buf
[2];
2190 word
|= (u32_t
) buf
[1];
2192 word
|= (u32_t
) buf
[0];
2199 /*============================================================================*/
2201 /*============================================================================*/
2202 /*== END DRXJ DAP FUNCTIONS ==*/
2203 /*============================================================================*/
2205 /*============================================================================*/
2206 /*============================================================================*/
2207 /*== HOST INTERFACE FUNCTIONS ==*/
2208 /*============================================================================*/
2209 /*============================================================================*/
2212 * \fn DRXStatus_t HICfgCommand()
2213 * \brief Configure HI with settings stored in the demod structure.
2214 * \param demod Demodulator.
2215 * \return DRXStatus_t.
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.
2222 static DRXStatus_t
HICfgCommand(const pDRXDemodInstance_t demod
)
2224 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
2228 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
;
2238 CHK_ERROR(HICommand(demod
->myI2CDevAddr
, &hiCmd
, &result
));
2240 /* Reset power down flag (set one call only) */
2241 extAttr
->HICfgCtrl
&= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ
));
2243 return (DRX_STS_OK
);
2246 return (DRX_STS_ERROR
);
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.
2257 * Sends command to HI
2261 HICommand(const pI2CDeviceAddr_t devAddr
, const pDRXJHiCmd_t cmd
, pu16_t result
)
2264 u16_t nrRetries
= 0;
2265 Bool_t powerdown_cmd
= FALSE
;
2267 /* Write parameters */
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
);
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
);
2281 case SIO_HI_RA_RAM_CMD_NULL
:
2286 return (DRX_STS_INVALID_ARG
);
2291 WR16(devAddr
, SIO_HI_RA_RAM_CMD__A
, cmd
->cmd
);
2293 if ((cmd
->cmd
) == SIO_HI_RA_RAM_CMD_RESET
) {
2294 /* Allow for HI to reset */
2295 DRXBSP_HST_Sleep(1);
2298 /* Detect power down to ommit reading result */
2299 powerdown_cmd
= (Bool_t
) ((cmd
->cmd
== SIO_HI_RA_RAM_CMD_CONFIG
) &&
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 */
2307 if (nrRetries
> DRXJ_MAX_RETRIES
) {
2311 RR16(devAddr
, SIO_HI_RA_RAM_CMD__A
, &waitCmd
);
2312 } while (waitCmd
!= 0);
2315 RR16(devAddr
, SIO_HI_RA_RAM_RES__A
, result
);
2318 /* if ( powerdown_cmd == TRUE ) */
2319 return (DRX_STS_OK
);
2321 return (DRX_STS_ERROR
);
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.
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.
2337 static DRXStatus_t
InitHI(const pDRXDemodInstance_t demod
)
2339 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
2340 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
) (NULL
);
2341 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) (NULL
);
2343 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
2344 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
2345 devAddr
= demod
->myI2CDevAddr
;
2347 /* PATCH for bug 5003, HI ucode v3.1.0 */
2348 WR16(devAddr
, 0x4301D7, 0x801);
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;
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
;
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
) /
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
;
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
;
2380 CHK_ERROR(HICfgCommand(demod
));
2382 return (DRX_STS_OK
);
2385 return (DRX_STS_ERROR
);
2388 /*============================================================================*/
2389 /*== END HOST INTERFACE FUNCTIONS ==*/
2390 /*============================================================================*/
2392 /*============================================================================*/
2393 /*============================================================================*/
2394 /*== AUXILIARY FUNCTIONS ==*/
2395 /*============================================================================*/
2396 /*============================================================================*/
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
2406 * Depending on pulldowns on MDx pins the following internals are set:
2407 * * commonAttr->oscClockFreq
2409 * * extAttr->hasNTSC
2410 * * extAttr->hasBTSC
2414 static DRXStatus_t
GetDeviceCapabilities(pDRXDemodInstance_t demod
)
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;
2423 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
2424 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
2425 devAddr
= demod
->myI2CDevAddr
;
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
);
2431 switch ((sioPdrOhwCfg
& SIO_PDR_OHW_CFG_FREF_SEL__M
)) {
2433 /* ignore (bypass ?) */
2437 commonAttr
->oscClockFreq
= 27000;
2441 commonAttr
->oscClockFreq
= 20250;
2445 commonAttr
->oscClockFreq
= 4000;
2448 return (DRX_STS_ERROR
);
2452 Determine device capabilities
2453 Based on pinning v47
2455 RR32(devAddr
, SIO_TOP_JTAGID_LO__A
, &sioTopJtagidLo
);
2456 extAttr
->mfx
= (u8_t
) ((sioTopJtagidLo
>> 29) & 0xF);
2458 switch ((sioTopJtagidLo
>> 12) & 0xFF) {
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
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
2565 /* Unknown device variant */
2566 return (DRX_STS_ERROR
);
2570 return (DRX_STS_OK
);
2572 return (DRX_STS_ERROR
);
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
2585 #ifndef DRXJ_MAX_RETRIES_POWERUP
2586 #define DRXJ_MAX_RETRIES_POWERUP 10
2589 static DRXStatus_t
PowerUpDevice(pDRXDemodInstance_t demod
)
2591 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) (NULL
);
2593 u16_t retryCount
= 0;
2594 I2CDeviceAddr_t wakeUpAddr
;
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) */
2605 DRXBSP_I2C_WriteRead(&wakeUpAddr
, 1, &data
,
2606 (pI2CDeviceAddr_t
) (NULL
), 0,
2608 DRXBSP_HST_Sleep(10);
2610 } while ((DRXBSP_I2C_WriteRead
2611 ((pI2CDeviceAddr_t
) (NULL
), 0, (pu8_t
) (NULL
), devAddr
, 1,
2613 != DRX_STS_OK
) && (retryCount
< DRXJ_MAX_RETRIES_POWERUP
));
2615 /* Need some recovery time .... */
2616 DRXBSP_HST_Sleep(10);
2618 if (retryCount
== DRXJ_MAX_RETRIES_POWERUP
) {
2619 return (DRX_STS_ERROR
);
2622 return (DRX_STS_OK
);
2625 /*----------------------------------------------------------------------------*/
2626 /* MPEG Output Configuration Functions - begin */
2627 /*----------------------------------------------------------------------------*/
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.
2635 * Configure MPEG output parameters.
2639 CtrlSetCfgMPEGOutput(pDRXDemodInstance_t demod
, pDRXCfgMPEGOutput_t cfgData
)
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;
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
);
2662 devAddr
= demod
->myI2CDevAddr
;
2663 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
2664 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
2666 if (cfgData
->enableMPEGOutput
== TRUE
) {
2667 /* quick and dirty patch to set MPEG incase current std is not
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
:
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
);
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);
2707 case DRX_STANDARD_ITU_A
:
2708 case DRX_STANDARD_ITU_C
:
2709 switch (extAttr
->constellation
) {
2710 case DRX_CONSTELLATION_QAM256
:
2713 case DRX_CONSTELLATION_QAM128
:
2716 case DRX_CONSTELLATION_QAM64
:
2719 case DRX_CONSTELLATION_QAM32
:
2722 case DRX_CONSTELLATION_QAM16
:
2726 return (DRX_STS_ERROR
);
2727 } /* extAttr->constellation */
2728 /* maxBitRate = symbolRate * nrBits * coef */
2729 /* coef = 188/204 */
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);
2746 WR16(devAddr
, FEC_OC_RCN_GAIN__A
,
2747 FEC_OC_RCN_GAIN__PRE
);
2749 WR16(devAddr
, FEC_OC_SNC_LWM__A
, 2);
2750 WR16(devAddr
, FEC_OC_SNC_HWM__A
, 12);
2754 } /* swtich (standard) */
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;
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;
2774 case DRX_CONSTELLATION_QAM64
:
2775 rcnRate
= 0x005F64D4;
2778 return (DRX_STS_ERROR
);
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 */
2787 (u32_t
) (commonAttr
->sysClockFreq
/ 8))) /
2791 return (DRX_STS_ERROR
);
2792 } /* extAttr->standard */
2793 } else { /* insertRSByte == FALSE */
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;
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;
2809 case DRX_CONSTELLATION_QAM64
:
2810 rcnRate
= 0x005AEC1A;
2813 return (DRX_STS_ERROR
);
2816 case DRX_STANDARD_ITU_A
:
2817 case DRX_STANDARD_ITU_C
:
2818 /* insertRSByte = FALSE -> coef = 188/204, RS bits not in MPEG output */
2822 (u32_t
) (commonAttr
->sysClockFreq
/ 8))) /
2826 return (DRX_STS_ERROR
);
2827 } /* extAttr->standard */
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
;
2836 /* Control slective inversion of output bits */
2837 if (cfgData
->invertDATA
== TRUE
) {
2838 fecOcRegIprInvert
|= InvertDataMask
;
2840 fecOcRegIprInvert
&= (~(InvertDataMask
));
2843 if (cfgData
->invertERR
== TRUE
) {
2844 fecOcRegIprInvert
|= FEC_OC_IPR_INVERT_MERR__M
;
2846 fecOcRegIprInvert
&= (~(FEC_OC_IPR_INVERT_MERR__M
));
2849 if (cfgData
->invertSTR
== TRUE
) {
2850 fecOcRegIprInvert
|= FEC_OC_IPR_INVERT_MSTRT__M
;
2852 fecOcRegIprInvert
&= (~(FEC_OC_IPR_INVERT_MSTRT__M
));
2855 if (cfgData
->invertVAL
== TRUE
) {
2856 fecOcRegIprInvert
|= FEC_OC_IPR_INVERT_MVAL__M
;
2858 fecOcRegIprInvert
&= (~(FEC_OC_IPR_INVERT_MVAL__M
));
2861 if (cfgData
->invertCLK
== TRUE
) {
2862 fecOcRegIprInvert
|= FEC_OC_IPR_INVERT_MCLK__M
;
2864 fecOcRegIprInvert
&= (~(FEC_OC_IPR_INVERT_MCLK__M
));
2867 if (cfgData
->staticCLK
== TRUE
) { /* Static mode */
2870 u16_t fecOcDtoBurstLen
= 0;
2871 u16_t fecOcDtoPeriod
= 0;
2873 fecOcDtoBurstLen
= FEC_OC_DTO_BURST_LEN__PRE
;
2875 switch (extAttr
->standard
) {
2876 case DRX_STANDARD_8VSB
:
2878 if (cfgData
->insertRSByte
== TRUE
) {
2879 fecOcDtoBurstLen
= 208;
2882 case DRX_STANDARD_ITU_A
:
2884 u32_t symbolRateTh
= 6400000;
2885 if (cfgData
->insertRSByte
== TRUE
) {
2886 fecOcDtoBurstLen
= 204;
2887 symbolRateTh
= 5900000;
2889 if (extAttr
->currSymbolRate
>=
2897 case DRX_STANDARD_ITU_B
:
2899 if (cfgData
->insertRSByte
== TRUE
) {
2900 fecOcDtoBurstLen
= 128;
2903 case DRX_STANDARD_ITU_C
:
2905 if (cfgData
->insertRSByte
== TRUE
) {
2906 fecOcDtoBurstLen
= 204;
2910 return (DRX_STS_ERROR
);
2913 commonAttr
->sysClockFreq
* 1000 / (fecOcDtoPeriod
+
2916 Frac28(bitRate
, commonAttr
->sysClockFreq
* 1000);
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
,
2930 if (extAttr
->mpegOutputClockRate
!=
2931 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
)
2933 extAttr
->mpegOutputClockRate
- 1;
2934 WR16(devAddr
, FEC_OC_DTO_PERIOD__A
, fecOcDtoPeriod
);
2935 } else { /* Dynamic mode */
2937 WR16(devAddr
, FEC_OC_DTO_MODE__A
,
2938 FEC_OC_DTO_MODE_DYNAMIC__M
);
2939 WR16(devAddr
, FEC_OC_FCT_MODE__A
, 0);
2942 WR32(devAddr
, FEC_OC_RCN_CTL_RATE_LO__A
, rcnRate
);
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
);
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);
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 */
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);
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);
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);
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
;
3023 return (DRX_STS_OK
);
3025 return (DRX_STS_ERROR
);
3028 /*----------------------------------------------------------------------------*/
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.
3037 * Retrieve MPEG output configuartion.
3041 CtrlGetCfgMPEGOutput(pDRXDemodInstance_t demod
, pDRXCfgMPEGOutput_t cfgData
)
3043 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) (NULL
);
3044 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
) (NULL
);
3045 DRXLockStatus_t lockStatus
= DRX_NOT_LOCKED
;
3050 if (cfgData
== NULL
) {
3051 return (DRX_STS_INVALID_ARG
);
3053 devAddr
= demod
->myI2CDevAddr
;
3054 commonAttr
= demod
->myCommonAttr
;
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;
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
,
3073 cfgData
->bitrate
= (data64Hi
<< 7) | (data64Lo
>> 25);
3076 return (DRX_STS_OK
);
3078 return (DRX_STS_ERROR
);
3081 /*----------------------------------------------------------------------------*/
3082 /* MPEG Output Configuration Functions - end */
3083 /*----------------------------------------------------------------------------*/
3085 /*----------------------------------------------------------------------------*/
3086 /* miscellaneous configuartions - begin */
3087 /*----------------------------------------------------------------------------*/
3090 * \fn DRXStatus_t SetMPEGTEIHandling()
3091 * \brief Activate MPEG TEI handling settings.
3092 * \param devmod Pointer to demodulator instance.
3093 * \return DRXStatus_t.
3095 * This routine should be called during a set channel of QAM/VSB
3098 static DRXStatus_t
SetMPEGTEIHandling(pDRXDemodInstance_t demod
)
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;
3106 devAddr
= demod
->myI2CDevAddr
;
3107 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
);
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
);
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
));
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
);
3131 return (DRX_STS_OK
);
3133 return (DRX_STS_ERROR
);
3136 /*----------------------------------------------------------------------------*/
3138 * \fn DRXStatus_t BitReverseMPEGOutput()
3139 * \brief Set MPEG output bit-endian settings.
3140 * \param devmod Pointer to demodulator instance.
3141 * \return DRXStatus_t.
3143 * This routine should be called during a set channel of QAM/VSB
3146 static DRXStatus_t
BitReverseMPEGOutput(pDRXDemodInstance_t demod
)
3148 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3149 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) (NULL
);
3150 u16_t fecOcIprMode
= 0;
3152 devAddr
= demod
->myI2CDevAddr
;
3153 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
3155 RR16(devAddr
, FEC_OC_IPR_MODE__A
, &fecOcIprMode
);
3157 /* reset to default (normal bit order) */
3158 fecOcIprMode
&= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M
);
3160 if (extAttr
->bitReverseMpegOutout
== TRUE
) {
3161 /* reverse bit order */
3162 fecOcIprMode
|= FEC_OC_IPR_MODE_REVERSE_ORDER__M
;
3165 WR16(devAddr
, FEC_OC_IPR_MODE__A
, fecOcIprMode
);
3167 return (DRX_STS_OK
);
3169 return (DRX_STS_ERROR
);
3172 /*----------------------------------------------------------------------------*/
3174 * \fn DRXStatus_t SetMPEGOutputClockRate()
3175 * \brief Set MPEG output clock rate.
3176 * \param devmod Pointer to demodulator instance.
3177 * \return DRXStatus_t.
3179 * This routine should be called during a set channel of QAM/VSB
3182 static DRXStatus_t
SetMPEGOutputClockRate(pDRXDemodInstance_t demod
)
3184 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3185 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) (NULL
);
3187 devAddr
= demod
->myI2CDevAddr
;
3188 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
3190 if (extAttr
->mpegOutputClockRate
!= DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
) {
3191 WR16(devAddr
, FEC_OC_DTO_PERIOD__A
,
3192 extAttr
->mpegOutputClockRate
- 1);
3195 return (DRX_STS_OK
);
3197 return (DRX_STS_ERROR
);
3200 /*----------------------------------------------------------------------------*/
3202 * \fn DRXStatus_t SetMPEGStartWidth()
3203 * \brief Set MPEG start width.
3204 * \param devmod Pointer to demodulator instance.
3205 * \return DRXStatus_t.
3207 * This routine should be called during a set channel of QAM/VSB
3210 static DRXStatus_t
SetMPEGStartWidth(pDRXDemodInstance_t demod
)
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
;
3217 devAddr
= demod
->myI2CDevAddr
;
3218 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
3219 commonAttr
= demod
->myCommonAttr
;
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
;
3228 WR16(devAddr
, FEC_OC_COMM_MB__A
, fecOcCommMb
);
3231 return (DRX_STS_OK
);
3233 return (DRX_STS_ERROR
);
3236 /*----------------------------------------------------------------------------*/
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.
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.
3249 CtrlSetCfgMpegOutputMisc(pDRXDemodInstance_t demod
,
3250 pDRXJCfgMpegOutputMisc_t cfgData
)
3252 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3254 if (cfgData
== NULL
) {
3255 return (DRX_STS_INVALID_ARG
);
3258 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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.
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
));
3279 return (DRX_STS_OK
);
3281 return (DRX_STS_ERROR
);
3284 /*----------------------------------------------------------------------------*/
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.
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
3299 CtrlGetCfgMpegOutputMisc(pDRXDemodInstance_t demod
,
3300 pDRXJCfgMpegOutputMisc_t cfgData
)
3302 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3305 if (cfgData
== NULL
) {
3306 return (DRX_STS_INVALID_ARG
);
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
;
3316 RR16(demod
->myI2CDevAddr
, FEC_OC_DTO_PERIOD__A
, &data
);
3317 cfgData
->mpegOutputClockRate
=
3318 (DRXJMpegOutputClockRate_t
) (data
+ 1);
3321 return (DRX_STS_OK
);
3323 return (DRX_STS_ERROR
);
3326 /*----------------------------------------------------------------------------*/
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.
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
3341 CtrlGetCfgHwCfg(pDRXDemodInstance_t demod
, pDRXJCfgHwCfg_t cfgData
)
3344 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3346 if (cfgData
== NULL
) {
3347 return (DRX_STS_INVALID_ARG
);
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);
3355 cfgData
->i2cSpeed
= (DRXJI2CSpeed_t
) ((data
>> 6) & 0x1);
3356 cfgData
->xtalFreq
= (DRXJXtalFreq_t
) (data
& 0x3);
3358 return (DRX_STS_OK
);
3360 return (DRX_STS_ERROR
);
3363 /*----------------------------------------------------------------------------*/
3364 /* miscellaneous configuartions - end */
3365 /*----------------------------------------------------------------------------*/
3367 /*----------------------------------------------------------------------------*/
3368 /* UIO Configuration Functions - begin */
3369 /*----------------------------------------------------------------------------*/
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.
3377 static DRXStatus_t
CtrlSetUIOCfg(pDRXDemodInstance_t demod
, pDRXUIOCfg_t UIOCfg
)
3379 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3381 if ((UIOCfg
== NULL
) || (demod
== NULL
)) {
3382 return DRX_STS_INVALID_ARG
;
3384 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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 /*====================================================================*/
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
;
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);
3406 return DRX_STS_INVALID_ARG
;
3407 } /* switch ( UIOCfg->mode ) */
3409 /*====================================================================*/
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
;
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);
3425 return DRX_STS_INVALID_ARG
;
3427 } /* switch ( UIOCfg->mode ) */
3429 /*====================================================================*/
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
;
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);
3445 return DRX_STS_INVALID_ARG
;
3447 } /* switch ( UIOCfg->mode ) */
3449 /*====================================================================*/
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
;
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
;
3463 case DRX_UIO_MODE_FIRMWARE0
: /* falltrough */
3465 return DRX_STS_INVALID_ARG
;
3467 } /* switch ( UIOCfg->mode ) */
3469 /*====================================================================*/
3471 return DRX_STS_INVALID_ARG
;
3472 } /* switch ( UIOCfg->uio ) */
3474 /* Write magic word to disable pdr reg write */
3475 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
3477 return (DRX_STS_OK
);
3479 return (DRX_STS_ERROR
);
3482 /*============================================================================*/
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.
3490 static DRXStatus_t
CtrlGetUIOCfg(pDRXDemodInstance_t demod
, pDRXUIOCfg_t UIOCfg
)
3493 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
3494 pDRXUIOMode_t UIOMode
[4] = { NULL
};
3495 pBool_t UIOAvailable
[4] = { NULL
};
3497 extAttr
= demod
->myExtAttr
;
3499 UIOMode
[DRX_UIO1
] = &extAttr
->uioSmaTxMode
;
3500 UIOMode
[DRX_UIO2
] = &extAttr
->uioSmaRxMode
;
3501 UIOMode
[DRX_UIO3
] = &extAttr
->uioGPIOMode
;
3502 UIOMode
[DRX_UIO4
] = &extAttr
->uioIRQNMode
;
3504 UIOAvailable
[DRX_UIO1
] = &extAttr
->hasSMATX
;
3505 UIOAvailable
[DRX_UIO2
] = &extAttr
->hasSMARX
;
3506 UIOAvailable
[DRX_UIO3
] = &extAttr
->hasGPIO
;
3507 UIOAvailable
[DRX_UIO4
] = &extAttr
->hasIRQN
;
3509 if (UIOCfg
== NULL
) {
3510 return DRX_STS_INVALID_ARG
;
3513 if ((UIOCfg
->uio
> DRX_UIO4
) || (UIOCfg
->uio
< DRX_UIO1
)) {
3514 return DRX_STS_INVALID_ARG
;
3517 if (*UIOAvailable
[UIOCfg
->uio
] == FALSE
) {
3518 return DRX_STS_ERROR
;
3521 UIOCfg
->mode
= *UIOMode
[UIOCfg
->uio
];
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.
3534 CtrlUIOWrite(pDRXDemodInstance_t demod
, pDRXUIOData_t UIOData
)
3536 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3537 u16_t pinCfgValue
= 0;
3540 if ((UIOData
== NULL
) || (demod
== NULL
)) {
3541 return DRX_STS_INVALID_ARG
;
3544 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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 /*====================================================================*/
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
;
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) */
3564 /* write to io pad configuration register - output mode */
3565 WR16(demod
->myI2CDevAddr
, SIO_PDR_SMA_TX_CFG__A
, pinCfgValue
);
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 */
3572 value
|= 0x8000; /* write one to 15th bit - 1st UIO */
3574 /* write back to io data output register */
3575 WR16(demod
->myI2CDevAddr
, SIO_PDR_UIO_OUT_LO__A
, value
);
3577 /*======================================================================*/
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
;
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) */
3591 /* write to io pad configuration register - output mode */
3592 WR16(demod
->myI2CDevAddr
, SIO_PDR_SMA_RX_CFG__A
, pinCfgValue
);
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 */
3599 value
|= 0x4000; /* write one to 14th bit - 2nd UIO */
3601 /* write back to io data output register */
3602 WR16(demod
->myI2CDevAddr
, SIO_PDR_UIO_OUT_LO__A
, value
);
3604 /*====================================================================*/
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
;
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) */
3618 /* write to io pad configuration register - output mode */
3619 WR16(demod
->myI2CDevAddr
, SIO_PDR_GPIO_CFG__A
, pinCfgValue
);
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 */
3626 value
|= 0x0004; /* write one to 2nd bit - 3rd UIO */
3628 /* write back to io data output register */
3629 WR16(demod
->myI2CDevAddr
, SIO_PDR_UIO_OUT_HI__A
, value
);
3631 /*=====================================================================*/
3633 /* DRX_UIO4: IRQN UIO-4 */
3634 if (extAttr
->hasIRQN
!= TRUE
)
3635 return DRX_STS_ERROR
;
3637 if (extAttr
->uioIRQNMode
!= DRX_UIO_MODE_READWRITE
) {
3638 return DRX_STS_ERROR
;
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) */
3646 /* write to io pad configuration register - output mode */
3647 WR16(demod
->myI2CDevAddr
, SIO_PDR_IRQN_CFG__A
, pinCfgValue
);
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 */
3654 value
|= 0x1000; /* write one to 12th bit - 4th UIO */
3656 /* write back to io data output register */
3657 WR16(demod
->myI2CDevAddr
, SIO_PDR_UIO_OUT_LO__A
, value
);
3659 /*=====================================================================*/
3661 return DRX_STS_INVALID_ARG
;
3662 } /* switch ( UIOData->uio ) */
3664 /* Write magic word to disable pdr reg write */
3665 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
3667 return (DRX_STS_OK
);
3669 return (DRX_STS_ERROR
);
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.
3679 static DRXStatus_t
CtrlUIORead(pDRXDemodInstance_t demod
, pDRXUIOData_t UIOData
)
3681 pDRXJData_t extAttr
= (pDRXJData_t
) (NULL
);
3682 u16_t pinCfgValue
= 0;
3685 if ((UIOData
== NULL
) || (demod
== NULL
)) {
3686 return DRX_STS_INVALID_ARG
;
3689 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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 /*====================================================================*/
3696 /* DRX_UIO1: SMA_TX UIO-1 */
3697 if (extAttr
->hasSMATX
!= TRUE
)
3698 return DRX_STS_ERROR
;
3700 if (extAttr
->uioSmaTxMode
!= DRX_UIO_MODE_READWRITE
) {
3701 return DRX_STS_ERROR
;
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) */
3709 /* write to io pad configuration register - input mode */
3710 WR16(demod
->myI2CDevAddr
, SIO_PDR_SMA_TX_CFG__A
, pinCfgValue
);
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
;
3716 UIOData
->value
= FALSE
;
3719 /*======================================================================*/
3721 /* DRX_UIO2: SMA_RX UIO-2 */
3722 if (extAttr
->hasSMARX
!= TRUE
)
3723 return DRX_STS_ERROR
;
3725 if (extAttr
->uioSmaRxMode
!= DRX_UIO_MODE_READWRITE
) {
3726 return DRX_STS_ERROR
;
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) */
3734 /* write to io pad configuration register - input mode */
3735 WR16(demod
->myI2CDevAddr
, SIO_PDR_SMA_RX_CFG__A
, pinCfgValue
);
3737 RR16(demod
->myI2CDevAddr
, SIO_PDR_UIO_IN_LO__A
, &value
);
3739 if ((value
& 0x4000) != 0) { /* check 14th bit - 2nd UIO */
3740 UIOData
->value
= TRUE
;
3742 UIOData
->value
= FALSE
;
3745 /*=====================================================================*/
3747 /* DRX_UIO3: GPIO UIO-3 */
3748 if (extAttr
->hasGPIO
!= TRUE
)
3749 return DRX_STS_ERROR
;
3751 if (extAttr
->uioGPIOMode
!= DRX_UIO_MODE_READWRITE
) {
3752 return DRX_STS_ERROR
;
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) */
3760 /* write to io pad configuration register - input mode */
3761 WR16(demod
->myI2CDevAddr
, SIO_PDR_GPIO_CFG__A
, pinCfgValue
);
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
;
3768 UIOData
->value
= FALSE
;
3771 /*=====================================================================*/
3773 /* DRX_UIO4: IRQN UIO-4 */
3774 if (extAttr
->hasIRQN
!= TRUE
)
3775 return DRX_STS_ERROR
;
3777 if (extAttr
->uioIRQNMode
!= DRX_UIO_MODE_READWRITE
) {
3778 return DRX_STS_ERROR
;
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) */
3786 /* write to io pad configuration register - input mode */
3787 WR16(demod
->myI2CDevAddr
, SIO_PDR_IRQN_CFG__A
, pinCfgValue
);
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
;
3794 UIOData
->value
= FALSE
;
3797 /*====================================================================*/
3799 return DRX_STS_INVALID_ARG
;
3800 } /* switch ( UIOData->uio ) */
3802 /* Write magic word to disable pdr reg write */
3803 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
3805 return (DRX_STS_OK
);
3807 return (DRX_STS_ERROR
);
3810 /*---------------------------------------------------------------------------*/
3811 /* UIO Configuration Functions - end */
3812 /*---------------------------------------------------------------------------*/
3814 /*----------------------------------------------------------------------------*/
3815 /* I2C Bridge Functions - begin */
3816 /*----------------------------------------------------------------------------*/
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.
3826 CtrlI2CBridge(pDRXDemodInstance_t demod
, pBool_t bridgeClosed
)
3831 /* check arguments */
3832 if (bridgeClosed
== NULL
) {
3833 return (DRX_STS_INVALID_ARG
);
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
;
3841 hiCmd
.param2
= SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN
;
3844 return HICommand(demod
->myI2CDevAddr
, &hiCmd
, &result
);
3847 /*----------------------------------------------------------------------------*/
3848 /* I2C Bridge Functions - end */
3849 /*----------------------------------------------------------------------------*/
3851 /*----------------------------------------------------------------------------*/
3852 /* Smart antenna Functions - begin */
3853 /*----------------------------------------------------------------------------*/
3855 * \fn DRXStatus_t SmartAntInit()
3856 * \brief Initialize Smart Antenna.
3857 * \param pointer to DRXDemodInstance_t.
3858 * \return DRXStatus_t.
3861 static DRXStatus_t
SmartAntInit(pDRXDemodInstance_t demod
)
3864 pDRXJData_t extAttr
= NULL
;
3865 pI2CDeviceAddr_t devAddr
= NULL
;
3866 DRXUIOCfg_t UIOCfg
= { DRX_UIO1
, DRX_UIO_MODE_FIRMWARE_SMA
};
3868 devAddr
= demod
->myI2CDevAddr
;
3869 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
);
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
);
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);
3889 /* Write magic word to disable pdr reg write */
3890 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
3892 return (DRX_STS_OK
);
3894 return (DRX_STS_ERROR
);
3898 * \fn DRXStatus_t CtrlSetCfgSmartAnt()
3899 * \brief Set Smart Antenna.
3900 * \param pointer to DRXJCfgSmartAnt_t.
3901 * \return DRXStatus_t.
3905 CtrlSetCfgSmartAnt(pDRXDemodInstance_t demod
, pDRXJCfgSmartAnt_t smartAnt
)
3907 pDRXJData_t extAttr
= NULL
;
3908 pI2CDeviceAddr_t devAddr
= NULL
;
3910 u32_t startTime
= 0;
3911 static Bool_t bitInverted
= FALSE
;
3913 devAddr
= demod
->myI2CDevAddr
;
3914 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
3916 /* check arguments */
3917 if (smartAnt
== NULL
) {
3918 return (DRX_STS_INVALID_ARG
);
3921 if (bitInverted
!= extAttr
->smartAntInverted
3922 || extAttr
->uioSmaTxMode
!= DRX_UIO_MODE_FIRMWARE_SMA
) {
3923 CHK_ERROR(SmartAntInit(demod
));
3924 bitInverted
= extAttr
->smartAntInverted
;
3927 /* Write magic word to enable pdr reg write */
3928 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
);
3930 switch (smartAnt
->io
) {
3931 case DRXJ_SMT_ANT_OUTPUT
:
3932 /* enable Tx if Mode B (input) is supported */
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 );
3937 startTime
= DRXBSP_HST_Clock();
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
));
3944 if (data
& SIO_SA_TX_STATUS_BUSY__M
) {
3945 return (DRX_STS_ERROR
);
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)
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)
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)
3969 WR16(devAddr
, SIO_SA_TX_DATA3__A
, 0xff8d);
3971 /* trigger the sending */
3972 WR16(devAddr
, SIO_SA_TX_LENGTH__A
, 56);
3975 case DRXJ_SMT_ANT_INPUT
:
3976 /* disable Tx if Mode B (input) is supported */
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) );
3982 return (DRX_STS_INVALID_ARG
);
3984 /* Write magic word to enable pdr reg write */
3985 WR16(demod
->myI2CDevAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
3987 return (DRX_STS_OK
);
3989 return (DRX_STS_ERROR
);
3992 static DRXStatus_t
SCUCommand(pI2CDeviceAddr_t devAddr
, pDRXJSCUCmd_t cmd
)
3995 u32_t startTime
= 0;
3999 return (DRX_STS_INVALID_ARG
);
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
);
4007 switch (cmd
->parameterLen
) {
4009 WR16(devAddr
, SCU_RAM_PARAM_4__A
, *(cmd
->parameter
+ 4)); /* fallthrough */
4011 WR16(devAddr
, SCU_RAM_PARAM_3__A
, *(cmd
->parameter
+ 3)); /* fallthrough */
4013 WR16(devAddr
, SCU_RAM_PARAM_2__A
, *(cmd
->parameter
+ 2)); /* fallthrough */
4015 WR16(devAddr
, SCU_RAM_PARAM_1__A
, *(cmd
->parameter
+ 1)); /* fallthrough */
4017 WR16(devAddr
, SCU_RAM_PARAM_0__A
, *(cmd
->parameter
+ 0)); /* fallthrough */
4022 /* this number of parameters is not supported */
4023 return (DRX_STS_ERROR
);
4025 WR16(devAddr
, SCU_RAM_COMMAND__A
, cmd
->command
);
4027 /* Wait until SCU has processed command */
4028 startTime
= DRXBSP_HST_Clock();
4030 RR16(devAddr
, SCU_RAM_COMMAND__A
, &curCmd
);
4031 } while (!(curCmd
== DRX_SCU_READY
)
4032 && ((DRXBSP_HST_Clock() - startTime
) < DRXJ_MAX_WAITTIME
));
4034 if (curCmd
!= DRX_SCU_READY
) {
4035 return (DRX_STS_ERROR
);
4039 if ((cmd
->resultLen
> 0) && (cmd
->result
!= NULL
)) {
4042 switch (cmd
->resultLen
) {
4044 RR16(devAddr
, SCU_RAM_PARAM_3__A
, cmd
->result
+ 3); /* fallthrough */
4046 RR16(devAddr
, SCU_RAM_PARAM_2__A
, cmd
->result
+ 2); /* fallthrough */
4048 RR16(devAddr
, SCU_RAM_PARAM_1__A
, cmd
->result
+ 1); /* fallthrough */
4050 RR16(devAddr
, SCU_RAM_PARAM_0__A
, cmd
->result
+ 0); /* fallthrough */
4055 /* this number of parameters is not supported */
4056 return (DRX_STS_ERROR
);
4059 /* Check if an error was reported by SCU */
4060 err
= cmd
->result
[0];
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
)
4068 return DRX_STS_INVALID_ARG
;
4070 /* here it is assumed that negative means error, and positive no error */
4072 return DRX_STS_ERROR
;
4078 return (DRX_STS_OK
);
4081 return (DRX_STS_ERROR
);
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
4096 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
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
)
4101 DRXJSCUCmd_t scuCmd
;
4102 u16_t setParamParameters
[15];
4103 u16_t cmdResult
[15];
4105 /* Parameter check */
4106 if ((data
== NULL
) ||
4107 (devAddr
== NULL
) || ((datasize
% 2) != 0) || ((datasize
/ 2) > 16)
4109 return (DRX_STS_INVALID_ARG
);
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;
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));
4125 scuCmd
.parameterLen
= datasize
/ 2 + 2;
4126 scuCmd
.resultLen
= 1;
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
));
4136 if (readFlag
== TRUE
) {
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);
4148 return (DRX_STS_ERROR
);
4152 /*============================================================================*/
4155 * \fn DRXStatus_t DRXJ_DAP_AtomicReadReg16()
4156 * \brief Atomic read of 16 bits words
4159 DRXStatus_t
DRXJ_DAP_SCU_AtomicReadReg16(pI2CDeviceAddr_t devAddr
,
4161 pu16_t data
, DRXflags_t flags
)
4164 DRXStatus_t rc
= DRX_STS_ERROR
;
4168 return DRX_STS_INVALID_ARG
;
4171 rc
= DRXJ_DAP_SCU_AtomicReadWriteBlock(devAddr
, addr
, 2, buf
, TRUE
);
4173 word
= (u16_t
) (buf
[0] + (buf
[1] << 8));
4180 /*============================================================================*/
4182 * \fn DRXStatus_t DRXJ_DAP_SCU_AtomicWriteReg16()
4183 * \brief Atomic read of 16 bits words
4186 DRXStatus_t
DRXJ_DAP_SCU_AtomicWriteReg16(pI2CDeviceAddr_t devAddr
,
4188 u16_t data
, DRXflags_t flags
)
4191 DRXStatus_t rc
= DRX_STS_ERROR
;
4193 buf
[0] = (u8_t
) (data
& 0xff);
4194 buf
[1] = (u8_t
) ((data
>> 8) & 0xff);
4196 rc
= DRXJ_DAP_SCU_AtomicReadWriteBlock(devAddr
, addr
, 2, buf
, FALSE
);
4202 CtrlI2CWriteRead(pDRXDemodInstance_t demod
, pDRXI2CData_t i2cData
)
4204 return (DRX_STS_FUNC_NOT_AVAILABLE
);
4208 TunerI2CWriteRead(pTUNERInstance_t tuner
,
4209 pI2CDeviceAddr_t wDevAddr
,
4212 pI2CDeviceAddr_t rDevAddr
, u16_t rCount
, pu8_t rData
)
4214 pDRXDemodInstance_t demod
;
4215 DRXI2CData_t i2cData
=
4216 { 2, wDevAddr
, wCount
, wData
, rDevAddr
, rCount
, rData
};
4218 demod
= (pDRXDemodInstance_t
) (tuner
->myCommonAttr
->myUserData
);
4220 return (CtrlI2CWriteRead(demod
, &i2cData
));
4223 /* -------------------------------------------------------------------------- */
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
4233 static DRXStatus_t
ADCSyncMeasurement(pDRXDemodInstance_t demod
, pu16_t count
)
4236 pI2CDeviceAddr_t devAddr
= NULL
;
4238 devAddr
= demod
->myI2CDevAddr
;
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);
4244 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4245 CHK_ERROR(DRXBSP_HST_Sleep(1));
4248 RR16(devAddr
, IQM_AF_PHASE0__A
, &data
);
4250 *count
= *count
+ 1;
4252 RR16(devAddr
, IQM_AF_PHASE1__A
, &data
);
4254 *count
= *count
+ 1;
4256 RR16(devAddr
, IQM_AF_PHASE2__A
, &data
);
4258 *count
= *count
+ 1;
4261 return (DRX_STS_OK
);
4263 return (DRX_STS_ERROR
);
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
4273 * An IQM reset will also reset the results of this synchronization.
4274 * After an IQM reset this routine needs to be called again.
4278 static DRXStatus_t
ADCSynchronization(pDRXDemodInstance_t demod
)
4281 pI2CDeviceAddr_t devAddr
= NULL
;
4283 devAddr
= demod
->myI2CDevAddr
;
4285 CHK_ERROR(ADCSyncMeasurement(demod
, &count
));
4288 /* Try sampling on a diffrent edge */
4291 RR16(devAddr
, IQM_AF_CLKNEG__A
, &clkNeg
);
4293 clkNeg
^= IQM_AF_CLKNEG_CLKNEGDATA__M
;
4294 WR16(devAddr
, IQM_AF_CLKNEG__A
, clkNeg
);
4296 CHK_ERROR(ADCSyncMeasurement(demod
, &count
));
4300 /* TODO: implement fallback scenarios */
4301 return (DRX_STS_ERROR
);
4304 return (DRX_STS_OK
);
4306 return (DRX_STS_ERROR
);
4310 * \brief Configure IQM AF registers
4311 * \param demod instance of demodulator.
4313 * \return DRXStatus_t.
4315 static DRXStatus_t
IQMSetAf(pDRXDemodInstance_t demod
, Bool_t active
)
4318 pI2CDeviceAddr_t devAddr
= NULL
;
4319 pDRXJData_t extAttr
= NULL
;
4321 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4322 devAddr
= demod
->myI2CDevAddr
;
4325 RR16(devAddr
, IQM_AF_STDBY__A
, &data
);
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
)
4333 } else { /* active */
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
);
4341 WR16(devAddr
, IQM_AF_STDBY__A
, data
);
4343 return (DRX_STS_OK
);
4345 return (DRX_STS_ERROR
);
4348 /* -------------------------------------------------------------------------- */
4350 CtrlSetCfgATVOutput(pDRXDemodInstance_t demod
, pDRXJCfgAtvOutput_t outputCfg
);
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.
4359 CtrlSetCfgPdrSafeMode(pDRXDemodInstance_t demod
, pBool_t enable
)
4361 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
4362 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
4363 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
) NULL
;
4365 if (enable
== NULL
) {
4366 return (DRX_STS_INVALID_ARG
);
4369 devAddr
= demod
->myI2CDevAddr
;
4370 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4371 commonAttr
= demod
->myCommonAttr
;
4373 /* Write magic word to enable pdr reg write */
4374 WR16(devAddr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
);
4376 if (*enable
== TRUE
) {
4377 Bool_t bridgeEnabled
= FALSE
;
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
);
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
);
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
);
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
));
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
)));
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
);
4433 /* No need to restore MPEG pins;
4434 is done in SetStandard/SetChannel */
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
);
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
);
4456 /* PD_RF_AGC, PD_IF_AGC
4457 No need to restore; will be restored in SetStandard/SetChannel */
4460 No need to restore; will be restored in SetStandard/SetChannel */
4462 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
4463 Should be restored via DRX_CTRL_SET_AUD */
4466 /* Write magic word to disable pdr reg write */
4467 WR16(devAddr
, SIO_TOP_COMM_KEY__A
, 0x0000);
4468 extAttr
->pdrSafeMode
= *enable
;
4470 return (DRX_STS_OK
);
4473 return (DRX_STS_ERROR
);
4476 /* -------------------------------------------------------------------------- */
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.
4485 CtrlGetCfgPdrSafeMode(pDRXDemodInstance_t demod
, pBool_t enabled
)
4487 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
4489 if (enabled
== NULL
) {
4490 return (DRX_STS_INVALID_ARG
);
4493 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4494 *enabled
= extAttr
->pdrSafeMode
;
4496 return (DRX_STS_OK
);
4500 * \brief Verifies whether microcode can be loaded.
4501 * \param demod Demodulator instance.
4502 * \return DRXStatus_t.
4504 static DRXStatus_t
CtrlValidateUCode(pDRXDemodInstance_t demod
)
4506 u32_t mcDev
, mcPatch
;
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
4516 DRX_GET_MCVERTYPE(demod
, verType
);
4517 DRX_GET_MCDEV(demod
, mcDev
);
4518 DRX_GET_MCPATCH(demod
, mcPatch
);
4520 if (DRX_ISMCVERTYPE(verType
)) {
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
;
4532 /* Everything else: OK */
4536 /*============================================================================*/
4537 /*== END AUXILIARY FUNCTIONS ==*/
4538 /*============================================================================*/
4540 /*============================================================================*/
4541 /*============================================================================*/
4542 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4543 /*============================================================================*/
4544 /*============================================================================*/
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.
4552 static DRXStatus_t
InitAGC(pDRXDemodInstance_t demod
)
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;
4561 u16_t snsSumMax
= 0;
4562 u16_t clpSumMax
= 0;
4564 u16_t kiInnergainMin
= 0;
4567 u16_t ifIaccuHiTgtMin
= 0;
4569 u16_t agcKiDgain
= 0;
4571 u16_t clpCtrlMode
= 0;
4574 devAddr
= demod
->myI2CDevAddr
;
4575 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
4576 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4578 switch (extAttr
->standard
) {
4579 case DRX_STANDARD_8VSB
:
4581 clpDirTo
= (u16_t
) (-9);
4583 snsDirTo
= (u16_t
) (-9);
4584 kiInnergainMin
= (u16_t
) (-32768);
4587 ifIaccuHiTgtMin
= 2047;
4589 IngainTgtMax
= 16383;
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
);
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;
4613 clpDirTo
= (u16_t
) (-5);
4615 snsDirTo
= (u16_t
) (-3);
4618 ifIaccuHiTgtMin
= 2047;
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
);
4636 RR16(devAddr
, SCU_RAM_AGC_KI__A
, &agcKi
);
4638 WR16(devAddr
, SCU_RAM_AGC_KI__A
, agcKi
);
4641 #ifndef DRXJ_DIGITAL_ONLY
4642 case DRX_STANDARD_FM
:
4645 kiInnergainMin
= (u16_t
) (-32768);
4646 ifIaccuHiTgtMin
= 2047;
4650 clpDirTo
= (u16_t
) (-9);
4651 snsDirTo
= (u16_t
) (-9);
4652 IngainTgtMax
= 9000;
4654 pAgcIfSettings
= &(extAttr
->atvIfAgcCfg
);
4655 pAgcRfSettings
= &(extAttr
->atvRfAgcCfg
);
4656 WR16(devAddr
, SCU_RAM_AGC_INGAIN_TGT__A
, pAgcIfSettings
->top
);
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
:
4664 kiInnergainMin
= (u16_t
) (-32768);
4665 ifIaccuHiTgtMin
= 2047;
4669 clpDirTo
= (u16_t
) (-9);
4670 IngainTgtMax
= 9000;
4671 pAgcIfSettings
= &(extAttr
->atvIfAgcCfg
);
4672 pAgcRfSettings
= &(extAttr
->atvRfAgcCfg
);
4673 snsDirTo
= (u16_t
) (-9);
4675 WR16(devAddr
, SCU_RAM_AGC_INGAIN_TGT__A
, pAgcIfSettings
->top
);
4677 case DRX_STANDARD_PAL_SECAM_L
:
4678 case DRX_STANDARD_PAL_SECAM_LP
:
4681 kiInnergainMin
= (u16_t
) (-32768);
4682 ifIaccuHiTgtMin
= 2047;
4686 clpDirTo
= (u16_t
) (-9);
4687 snsDirTo
= (u16_t
) (-9);
4688 IngainTgtMax
= 9000;
4690 pAgcIfSettings
= &(extAttr
->atvIfAgcCfg
);
4691 pAgcRfSettings
= &(extAttr
->atvRfAgcCfg
);
4692 WR16(devAddr
, SCU_RAM_AGC_INGAIN_TGT__A
, pAgcIfSettings
->top
);
4696 return (DRX_STS_INVALID_ARG
);
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
);
4727 agcRf
= 0x800 + pAgcRfSettings
->cutOffCurrent
;
4728 if (commonAttr
->tunerRfAgcPol
== TRUE
) {
4729 agcRf
= 0x87ff - agcRf
;
4733 if (commonAttr
->tunerIfAgcPol
== TRUE
) {
4734 agcRf
= 0x87ff - agcRf
;
4737 WR16(devAddr
, IQM_AF_AGC_RF__A
, agcRf
);
4738 WR16(devAddr
, IQM_AF_AGC_IF__A
, agcIf
);
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
);
4746 return (DRX_STS_OK
);
4748 return (DRX_STS_ERROR
);
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.
4760 SetFrequency(pDRXDemodInstance_t demod
,
4761 pDRXChannel_t channel
, DRXFrequency_t tunerFreqOffset
)
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;
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
;
4787 Program frequency shifter
4788 No need to account for mirroring on RF
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
;
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
;
4811 return (DRX_STS_INVALID_ARG
);
4813 intermediateFreq
= demod
->myCommonAttr
->intermediateFreq
;
4814 samplingFrequency
= demod
->myCommonAttr
->sysClockFreq
/ 3;
4815 if (tunerMirror
== TRUE
) {
4816 /* tuner doesn't mirror */
4818 intermediateFreq
+ rfFreqResidual
+ fmFrequencyShift
;
4822 intermediateFreq
- rfFreqResidual
- fmFrequencyShift
;
4824 if (ifFreqActual
> samplingFrequency
/ 2) {
4826 adcFreq
= samplingFrequency
- ifFreqActual
;
4829 /* adc doesn't mirror */
4830 adcFreq
= ifFreqActual
;
4834 frequencyShift
= adcFreq
;
4836 (Bool_t
) (rfMirror
^ tunerMirror
^ adcFlip
^ selectPosImage
);
4837 iqmFsRateOfs
= Frac28(frequencyShift
, samplingFrequency
);
4840 iqmFsRateOfs
= ~iqmFsRateOfs
+ 1;
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
);
4848 return (DRX_STS_OK
);
4850 return (DRX_STS_ERROR
);
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.
4863 #define DRXJ_AGC_TOP 0x2800
4864 #define DRXJ_AGC_SNS 0x1600
4865 #define DRXJ_RFAGC_MAX 0x3fff
4866 #define DRXJ_RFAGC_MIN 0x800
4868 static DRXStatus_t
GetSigStrength(pDRXDemodInstance_t demod
, pu16_t sigStrength
)
4876 pDRXJData_t extAttr
= NULL
;
4877 pI2CDeviceAddr_t devAddr
= NULL
;
4879 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4880 devAddr
= demod
->myI2CDevAddr
;
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
;
4887 ifAgcSns
= DRXJ_AGC_SNS
;
4888 ifAgcTop
= DRXJ_AGC_TOP
;
4889 rfAgcMax
= DRXJ_RFAGC_MAX
;
4890 rfAgcMin
= DRXJ_RFAGC_MIN
;
4892 if (ifGain
> ifAgcTop
) {
4893 if (rfGain
> rfAgcMax
)
4895 else if (rfGain
> rfAgcMin
) {
4896 CHK_ZERO(rfAgcMax
- rfAgcMin
);
4898 75 + 25 * (rfGain
- rfAgcMin
) / (rfAgcMax
-
4902 } else if (ifGain
> ifAgcSns
) {
4903 CHK_ZERO(ifAgcTop
- ifAgcSns
);
4905 20 + 55 * (ifGain
- ifAgcSns
) / (ifAgcTop
- ifAgcSns
);
4908 *sigStrength
= (20 * ifGain
/ ifAgcSns
);
4911 return (DRX_STS_OK
);
4913 return (DRX_STS_ERROR
);
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.
4926 #ifdef DRXJ_SIGNAL_ACCUM_ERR
4927 static DRXStatus_t
GetAccPktErr(pDRXDemodInstance_t demod
, pu16_t packetErr
)
4929 static u16_t pktErr
= 0;
4930 static u16_t lastPktErr
= 0;
4932 pDRXJData_t extAttr
= NULL
;
4933 pI2CDeviceAddr_t devAddr
= NULL
;
4935 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4936 devAddr
= demod
->myI2CDevAddr
;
4938 RR16(devAddr
, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A
, &data
);
4939 if (extAttr
->resetPktErrAcc
== TRUE
) {
4942 extAttr
->resetPktErrAcc
= FALSE
;
4945 if (data
< lastPktErr
) {
4946 pktErr
+= 0xffff - lastPktErr
;
4949 pktErr
+= (data
- lastPktErr
);
4951 *packetErr
= pktErr
;
4954 return (DRX_STS_OK
);
4956 return (DRX_STS_ERROR
);
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.
4968 static DRXStatus_t
CtrlSetCfgResetPktErr(pDRXDemodInstance_t demod
)
4970 #ifdef DRXJ_SIGNAL_ACCUM_ERR
4971 pDRXJData_t extAttr
= NULL
;
4972 u16_t packetError
= 0;
4974 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
4975 extAttr
->resetPktErrAcc
= TRUE
;
4976 /* call to reset counter */
4977 CHK_ERROR(GetAccPktErr(demod
, &packetError
));
4979 return (DRX_STS_OK
);
4982 return (DRX_STS_ERROR
);
4986 * \fn static short GetSTRFreqOffset()
4987 * \brief Get symbol rate offset in QAM & 8VSB mode
4988 * \return Error code
4990 static DRXStatus_t
GetSTRFreqOffset(pDRXDemodInstance_t demod
, s32_t
* STRFreq
)
4992 u32_t symbolFrequencyRatio
= 0;
4993 u32_t symbolNomFrequencyRatio
= 0;
4995 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
4996 pI2CDeviceAddr_t devAddr
= NULL
;
4997 pDRXJData_t extAttr
= NULL
;
4999 devAddr
= demod
->myI2CDevAddr
;
5000 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5001 standard
= extAttr
->standard
;
5003 ARR32(devAddr
, IQM_RC_RATE_LO__A
, &symbolFrequencyRatio
);
5004 symbolNomFrequencyRatio
= extAttr
->iqmRcRateOfs
;
5006 if (symbolFrequencyRatio
> symbolNomFrequencyRatio
)
5009 FracTimes1e6((symbolFrequencyRatio
-
5010 symbolNomFrequencyRatio
),
5011 (symbolFrequencyRatio
+ (1 << 23)));
5014 FracTimes1e6((symbolNomFrequencyRatio
-
5015 symbolFrequencyRatio
),
5016 (symbolFrequencyRatio
+ (1 << 23)));
5018 return (DRX_STS_OK
);
5020 return (DRX_STS_ERROR
);
5024 * \fn static short GetCTLFreqOffset
5025 * \brief Get the value of CTLFreq in QAM & ATSC mode
5026 * \return Error code
5028 static DRXStatus_t
GetCTLFreqOffset(pDRXDemodInstance_t demod
, s32_t
* CTLFreq
)
5030 DRXFrequency_t samplingFrequency
= 0;
5031 s32_t currentFrequency
= 0;
5032 s32_t nominalFrequency
= 0;
5033 s32_t carrierFrequencyShift
= 0;
5037 pDRXJData_t extAttr
= NULL
;
5038 pDRXCommonAttr_t commonAttr
= NULL
;
5039 pI2CDeviceAddr_t devAddr
= NULL
;
5041 devAddr
= demod
->myI2CDevAddr
;
5042 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5043 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
5045 samplingFrequency
= commonAttr
->sysClockFreq
/ 3;
5047 /* both registers are sign extended */
5048 nominalFrequency
= extAttr
->iqmFsRateOfs
;
5049 ARR32(devAddr
, IQM_FS_RATE_LO__A
, (pu32_t
) & currentFrequency
);
5051 if (extAttr
->posImage
== TRUE
) {
5052 /* negative image */
5053 carrierFrequencyShift
= nominalFrequency
- currentFrequency
;
5055 /* positive image */
5056 carrierFrequencyShift
= currentFrequency
- nominalFrequency
;
5059 /* carrier Frequency Shift In Hz */
5060 if (carrierFrequencyShift
< 0) {
5062 carrierFrequencyShift
*= sign
;
5065 /* *CTLFreq = carrierFrequencyShift * 50.625e6 / (1 << 28); */
5066 Mult32(carrierFrequencyShift
, samplingFrequency
, &data64Hi
, &data64Lo
);
5068 (s32_t
) ((((data64Lo
>> 28) & 0xf) | (data64Hi
<< 4)) * sign
);
5070 return (DRX_STS_OK
);
5072 return (DRX_STS_ERROR
);
5075 /*============================================================================*/
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.
5085 SetAgcRf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
, Bool_t atomic
)
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
;
5094 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
5095 devAddr
= demod
->myI2CDevAddr
;
5096 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5099 ScuRr16
= DRXJ_DAP_SCU_AtomicReadReg16
;
5100 ScuWr16
= DRXJ_DAP_SCU_AtomicWriteReg16
;
5102 ScuRr16
= DRXJ_DAP
.readReg16Func
;
5103 ScuWr16
= DRXJ_DAP
.writeReg16Func
;
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
))) {
5114 switch (agcSettings
->ctrlMode
) {
5115 case DRX_AGC_CTRL_AUTO
:
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
);
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
);
5131 data
|= (4 << SCU_RAM_AGC_KI_RF__B
);
5134 if (commonAttr
->tunerRfAgcPol
) {
5135 data
|= SCU_RAM_AGC_KI_INV_RF_POL__M
;
5137 data
&= ~SCU_RAM_AGC_KI_INV_RF_POL__M
;
5139 CHK_ERROR((*ScuWr16
)
5140 (devAddr
, SCU_RAM_AGC_KI__A
, data
, 0));
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
,
5150 SCU_RAM_AGC_KI_RED_RAGC_RED__B
)
5151 & SCU_RAM_AGC_KI_RED_RAGC_RED__M
)
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
);
5161 return (DRX_STS_INVALID_ARG
);
5163 /* Set TOP, only if IF-AGC is in AUTO mode */
5164 if (pAgcSettings
->ctrlMode
== DRX_AGC_CTRL_AUTO
) {
5165 CHK_ERROR((*ScuWr16
)
5167 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
,
5168 agcSettings
->top
, 0));
5169 CHK_ERROR((*ScuWr16
)
5171 SCU_RAM_AGC_IF_IACCU_HI_TGT__A
,
5172 agcSettings
->top
, 0));
5175 /* Cut-Off current */
5176 CHK_ERROR((*ScuWr16
)
5177 (devAddr
, SCU_RAM_AGC_RF_IACCU_HI_CO__A
,
5178 agcSettings
->cutOffCurrent
, 0));
5180 case DRX_AGC_CTRL_USER
:
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
);
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
;
5194 data
&= ~SCU_RAM_AGC_KI_INV_RF_POL__M
;
5196 CHK_ERROR((*ScuWr16
)
5197 (devAddr
, SCU_RAM_AGC_KI__A
, data
, 0));
5199 /* Write value to output pin */
5200 CHK_ERROR((*ScuWr16
)
5201 (devAddr
, SCU_RAM_AGC_RF_IACCU_HI__A
,
5202 agcSettings
->outputLevel
, 0));
5204 case DRX_AGC_CTRL_OFF
:
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
);
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));
5219 return (DRX_STS_INVALID_ARG
);
5220 } /* switch ( agcsettings->ctrlMode ) */
5223 /* Store rf agc settings */
5224 switch (agcSettings
->standard
) {
5225 case DRX_STANDARD_8VSB
:
5226 extAttr
->vsbRfAgcCfg
= *agcSettings
;
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
;
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
;
5247 return (DRX_STS_ERROR
);
5250 return (DRX_STS_OK
);
5252 return (DRX_STS_ERROR
);
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.
5263 GetAgcRf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
5265 pI2CDeviceAddr_t devAddr
= NULL
;
5266 pDRXJData_t extAttr
= NULL
;
5267 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
5269 devAddr
= demod
->myI2CDevAddr
;
5270 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5272 /* Return stored AGC settings */
5273 standard
= agcSettings
->standard
;
5274 switch (agcSettings
->standard
) {
5275 case DRX_STANDARD_8VSB
:
5276 *agcSettings
= extAttr
->vsbRfAgcCfg
;
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
;
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
;
5297 return (DRX_STS_ERROR
);
5299 agcSettings
->standard
= standard
;
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
));
5311 return (DRX_STS_OK
);
5313 return (DRX_STS_ERROR
);
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.
5324 SetAgcIf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
, Bool_t atomic
)
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
;
5333 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
5334 devAddr
= demod
->myI2CDevAddr
;
5335 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5338 ScuRr16
= DRXJ_DAP_SCU_AtomicReadReg16
;
5339 ScuWr16
= DRXJ_DAP_SCU_AtomicWriteReg16
;
5341 ScuRr16
= DRXJ_DAP
.readReg16Func
;
5342 ScuWr16
= DRXJ_DAP
.writeReg16Func
;
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
))) {
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
);
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
);
5370 data
|= (5 << SCU_RAM_AGC_KI_IF__B
);
5373 if (commonAttr
->tunerIfAgcPol
) {
5374 data
|= SCU_RAM_AGC_KI_INV_IF_POL__M
;
5376 data
&= ~SCU_RAM_AGC_KI_INV_IF_POL__M
;
5378 CHK_ERROR((*ScuWr16
)
5379 (devAddr
, SCU_RAM_AGC_KI__A
, data
, 0));
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
,
5389 SCU_RAM_AGC_KI_RED_IAGC_RED__B
)
5390 & SCU_RAM_AGC_KI_RED_IAGC_RED__M
)
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
);
5400 return (DRX_STS_INVALID_ARG
);
5403 if (pAgcSettings
->ctrlMode
== DRX_AGC_CTRL_AUTO
) {
5404 CHK_ERROR((*ScuWr16
)
5406 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
,
5407 pAgcSettings
->top
, 0));
5408 CHK_ERROR((*ScuWr16
)
5410 SCU_RAM_AGC_IF_IACCU_HI_TGT__A
,
5411 pAgcSettings
->top
, 0));
5413 CHK_ERROR((*ScuWr16
)
5415 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
,
5417 CHK_ERROR((*ScuWr16
)
5419 SCU_RAM_AGC_IF_IACCU_HI_TGT__A
, 0,
5424 case DRX_AGC_CTRL_USER
:
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
);
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
;
5439 data
&= ~SCU_RAM_AGC_KI_INV_IF_POL__M
;
5441 CHK_ERROR((*ScuWr16
)
5442 (devAddr
, SCU_RAM_AGC_KI__A
, data
, 0));
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));
5450 case DRX_AGC_CTRL_OFF
:
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
);
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));
5466 return (DRX_STS_INVALID_ARG
);
5467 } /* switch ( agcsettings->ctrlMode ) */
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));
5475 /* Store if agc settings */
5476 switch (agcSettings
->standard
) {
5477 case DRX_STANDARD_8VSB
:
5478 extAttr
->vsbIfAgcCfg
= *agcSettings
;
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
;
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
;
5499 return (DRX_STS_ERROR
);
5502 return (DRX_STS_OK
);
5504 return (DRX_STS_ERROR
);
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.
5515 GetAgcIf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
5517 pI2CDeviceAddr_t devAddr
= NULL
;
5518 pDRXJData_t extAttr
= NULL
;
5519 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
5521 devAddr
= demod
->myI2CDevAddr
;
5522 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5524 /* Return stored ATV AGC settings */
5525 standard
= agcSettings
->standard
;
5526 switch (agcSettings
->standard
) {
5527 case DRX_STANDARD_8VSB
:
5528 *agcSettings
= extAttr
->vsbIfAgcCfg
;
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
;
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
;
5549 return (DRX_STS_ERROR
);
5551 agcSettings
->standard
= standard
;
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
));
5564 return (DRX_STS_OK
);
5566 return (DRX_STS_ERROR
);
5570 * \fn DRXStatus_t SetIqmAf ()
5571 * \brief Configure IQM AF registers
5572 * \param demod instance of demodulator.
5574 * \return DRXStatus_t.
5576 static DRXStatus_t
SetIqmAf(pDRXDemodInstance_t demod
, Bool_t active
)
5579 pI2CDeviceAddr_t devAddr
= NULL
;
5581 devAddr
= demod
->myI2CDevAddr
;
5584 RR16(devAddr
, IQM_AF_STDBY__A
, &data
);
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
)
5592 } else { /* active */
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
);
5600 WR16(devAddr
, IQM_AF_STDBY__A
, data
);
5602 return (DRX_STS_OK
);
5604 return (DRX_STS_ERROR
);
5607 /*============================================================================*/
5608 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5609 /*============================================================================*/
5611 /*============================================================================*/
5612 /*============================================================================*/
5613 /*== 8VSB DATAPATH FUNCTIONS ==*/
5614 /*============================================================================*/
5615 /*============================================================================*/
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.
5624 static DRXStatus_t
PowerDownVSB(pDRXDemodInstance_t demod
, Bool_t primary
)
5626 pI2CDeviceAddr_t devAddr
= NULL
;
5627 DRXJSCUCmd_t cmdSCU
= { /* command */ 0,
5628 /* parameterLen */ 0,
5630 /* *parameter */ NULL
,
5633 u16_t cmdResult
= 0;
5634 pDRXJData_t extAttr
= NULL
;
5635 DRXCfgMPEGOutput_t cfgMPEGOutput
;
5637 devAddr
= demod
->myI2CDevAddr
;
5638 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
5641 reset of FEC and VSB HW
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
));
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
));
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
);
5665 cfgMPEGOutput
.enableMPEGOutput
= FALSE
;
5666 CHK_ERROR(CtrlSetCfgMPEGOutput(demod
, &cfgMPEGOutput
));
5668 return (DRX_STS_OK
);
5670 return (DRX_STS_ERROR
);
5674 * \fn DRXStatus_t SetVSBLeakNGain ()
5675 * \brief Set ATSC demod.
5676 * \param demod instance of demodulator.
5677 * \return DRXStatus_t.
5679 static DRXStatus_t
SetVSBLeakNGain(pDRXDemodInstance_t demod
)
5681 pI2CDeviceAddr_t devAddr
= NULL
;
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 */
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 */
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
));
5877 return (DRX_STS_OK
);
5879 return (DRX_STS_ERROR
);
5883 * \fn DRXStatus_t SetVSB()
5884 * \brief Set 8VSB demod.
5885 * \param demod instance of demodulator.
5886 * \return DRXStatus_t.
5889 static DRXStatus_t
SetVSB(pDRXDemodInstance_t demod
)
5891 pI2CDeviceAddr_t devAddr
= NULL
;
5892 u16_t cmdResult
= 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 */
5928 devAddr
= demod
->myI2CDevAddr
;
5929 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
5930 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
);
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
));
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);
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);
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
));
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 */
5980 /* Initialize the FEC Subsystem */
5981 WR16(devAddr
, FEC_TOP_ANNEX__A
, FEC_TOP_ANNEX_D
);
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
);
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 */
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
)
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
);
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);
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);
6026 /* turn on IQMAF. It has to be in front of setAgc**() */
6027 CHK_ERROR(SetIqmAf(demod
, TRUE
));
6028 CHK_ERROR(ADCSynchronization(demod
));
6030 CHK_ERROR(InitAGC(demod
));
6031 CHK_ERROR(SetAgcIf(demod
, &(extAttr
->vsbIfAgcCfg
), FALSE
));
6032 CHK_ERROR(SetAgcRf(demod
, &(extAttr
->vsbRfAgcCfg
), FALSE
));
6034 /* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
6036 DRXJCfgAfeGain_t vsbPgaCfg
= { DRX_STANDARD_8VSB
, 0 };
6038 vsbPgaCfg
.gain
= extAttr
->vsbPgaCfg
;
6039 CHK_ERROR(CtrlSetCfgAfeGain(demod
, &vsbPgaCfg
));
6041 CHK_ERROR(CtrlSetCfgPreSaw(demod
, &(extAttr
->vsbPreSawCfg
)));
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
));
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
));
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
));
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);
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
));
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
);
6098 return (DRX_STS_OK
);
6100 return (DRX_STS_ERROR
);
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
6108 static DRXStatus_t
GetVSBPostRSPckErr(pI2CDeviceAddr_t devAddr
, pu16_t pckErrs
)
6113 u16_t packetErrorsMant
= 0;
6114 u16_t packetErrorsExp
= 0;
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
);
6126 (u16_t
) FracTimes1e6(packetErrorsMant
* (1 << packetErrorsExp
),
6127 (period
* prescale
* 77));
6129 return (DRX_STS_OK
);
6131 return (DRX_STS_ERROR
);
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
6139 static DRXStatus_t
GetVSBpostViterbiBer(pI2CDeviceAddr_t devAddr
, pu32_t ber
)
6144 u16_t bitErrorsMant
= 0;
6145 u16_t bitErrorsExp
= 0;
6147 RR16(devAddr
, FEC_RS_NR_BIT_ERRORS__A
, &data
);
6148 period
= FEC_RS_MEASUREMENT_PERIOD
;
6149 prescale
= FEC_RS_MEASUREMENT_PRESCALE
;
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
;
6155 if (((bitErrorsMant
<< bitErrorsExp
) >> 3) > 68700)
6158 CHK_ZERO(period
* prescale
);
6160 FracTimes1e6(bitErrorsMant
<<
6162 2) ? (bitErrorsExp
- 3) : bitErrorsExp
),
6163 period
* prescale
* 207 *
6164 ((bitErrorsExp
> 2) ? 1 : 8));
6167 return (DRX_STS_OK
);
6169 return (DRX_STS_ERROR
);
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
6177 static DRXStatus_t
GetVSBpreViterbiBer(pI2CDeviceAddr_t devAddr
, pu32_t ber
)
6181 RR16(devAddr
, VSB_TOP_NR_SYM_ERRS__A
, &data
);
6184 VSB_TOP_MEASUREMENT_PERIOD
* SYMBOLS_PER_SEGMENT
);
6186 return (DRX_STS_OK
);
6188 return (DRX_STS_ERROR
);
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
6196 static DRXStatus_t
GetVSBSymbErr(pI2CDeviceAddr_t devAddr
, pu32_t ser
)
6201 u16_t symbErrorsMant
= 0;
6202 u16_t symbErrorsExp
= 0;
6204 RR16(devAddr
, FEC_RS_NR_SYMBOL_ERRORS__A
, &data
);
6205 period
= FEC_RS_MEASUREMENT_PERIOD
;
6206 prescale
= FEC_RS_MEASUREMENT_PRESCALE
;
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
;
6212 CHK_ZERO(period
* prescale
);
6213 *ser
= (u32_t
) FracTimes1e6((symbErrorsMant
<< symbErrorsExp
) * 1000,
6214 (period
* prescale
* 77318));
6216 return (DRX_STS_OK
);
6218 return (DRX_STS_ERROR
);
6222 * \fn static DRXStatus_t GetVSBMER(pI2CDeviceAddr_t devAddr, pu16_t mer)
6223 * \brief Get the values of MER
6224 * \return Error code
6226 static DRXStatus_t
GetVSBMER(pI2CDeviceAddr_t devAddr
, pu16_t mer
)
6230 RR16(devAddr
, VSB_TOP_ERR_ENERGY_H__A
, &dataHi
);
6232 (u16_t
) (Log10Times100(21504) - Log10Times100((dataHi
<< 6) / 52));
6234 return (DRX_STS_OK
);
6236 return (DRX_STS_ERROR
);
6239 /*============================================================================*/
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.
6249 CtrlGetVSBConstel(pDRXDemodInstance_t demod
, pDRXComplex_t complexNr
)
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 */
6258 /* read device info */
6259 devAddr
= demod
->myI2CDevAddr
;
6262 /* Monitor bus grabbing is an open external interface issue */
6263 /* Needs to be checked when external interface PG is updated */
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
);
6273 /* Enable MB grabber in the FEC OC */
6274 WR16(devAddr
, FEC_OC_OCR_MODE__A
, FEC_OC_OCR_MODE_GRAB_ENABLE__M
);
6276 /* Disable MB grabber in the FEC OC */
6277 WR16(devAddr
, FEC_OC_OCR_MODE__A
, 0x0);
6280 RR32(devAddr
, FEC_OC_OCR_GRAB_RD1__A
, &data
);
6281 re
= (u16_t
) (((data
>> 10) & 0x300) | ((data
>> 2) & 0xff));
6288 /* Restore MB (Monitor bus) */
6289 WR16(devAddr
, VSB_TOP_COMM_MB__A
, vsbTopCommMbInit
);
6291 return (DRX_STS_OK
);
6293 return (DRX_STS_ERROR
);
6296 /*============================================================================*/
6297 /*== END 8VSB DATAPATH FUNCTIONS ==*/
6298 /*============================================================================*/
6300 /*============================================================================*/
6301 /*============================================================================*/
6302 /*== QAM DATAPATH FUNCTIONS ==*/
6303 /*============================================================================*/
6304 /*============================================================================*/
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.
6313 static DRXStatus_t
PowerDownQAM(pDRXDemodInstance_t demod
, Bool_t primary
)
6315 DRXJSCUCmd_t cmdSCU
= { /* command */ 0,
6316 /* parameterLen */ 0,
6318 /* *parameter */ NULL
,
6321 u16_t cmdResult
= 0;
6322 pI2CDeviceAddr_t devAddr
= NULL
;
6323 pDRXJData_t extAttr
= NULL
;
6324 DRXCfgMPEGOutput_t cfgMPEGOutput
;
6326 devAddr
= demod
->myI2CDevAddr
;
6327 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
6331 resets IQM, QAM and FEC HW blocks
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
);
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
));
6345 if (primary
== TRUE
) {
6346 WR16(devAddr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_STOP
);
6347 CHK_ERROR(SetIqmAf(demod
, FALSE
));
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
);
6356 cfgMPEGOutput
.enableMPEGOutput
= FALSE
;
6357 CHK_ERROR(CtrlSetCfgMPEGOutput(demod
, &cfgMPEGOutput
));
6359 return (DRX_STS_OK
);
6361 return (DRX_STS_ERROR
);
6364 /*============================================================================*/
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.
6374 * Take into account that for certain settings the errorcounters can overflow.
6375 * The implementation does not check this.
6377 * TODO: overriding the extAttr->fecBitsDesired by constellation dependent
6378 * constants to get a measurement period of approx. 1 sec. Remove fecBitsDesired
6382 #ifndef DRXJ_VSB_ONLY
6384 SetQAMMeasurement(pDRXDemodInstance_t demod
,
6385 DRXConstellation_t constellation
, u32_t symbolRate
)
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 */
6400 devAddr
= demod
->myI2CDevAddr
;
6401 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
6403 fecBitsDesired
= extAttr
->fecBitsDesired
;
6404 fecRsPrescale
= extAttr
->fecRsPrescale
;
6406 switch (constellation
) {
6407 case DRX_CONSTELLATION_QAM16
:
6408 fecBitsDesired
= 4 * symbolRate
;
6410 case DRX_CONSTELLATION_QAM32
:
6411 fecBitsDesired
= 5 * symbolRate
;
6413 case DRX_CONSTELLATION_QAM64
:
6414 fecBitsDesired
= 6 * symbolRate
;
6416 case DRX_CONSTELLATION_QAM128
:
6417 fecBitsDesired
= 7 * symbolRate
;
6419 case DRX_CONSTELLATION_QAM256
:
6420 fecBitsDesired
= 8 * symbolRate
;
6423 return (DRX_STS_INVALID_ARG
);
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 */
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;
6438 case DRX_STANDARD_ITU_B
:
6439 fecRsPlen
= 128 * 7;
6442 return (DRX_STS_INVALID_ARG
);
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
;
6452 /* limit to max 16 bit value (I2C register width) if needed */
6453 if (fecRsPeriod
> 0xFFFF)
6454 fecRsPeriod
= 0xFFFF;
6456 /* write corresponding registers */
6457 switch (extAttr
->standard
) {
6458 case DRX_STANDARD_ITU_A
:
6459 case DRX_STANDARD_ITU_C
:
6461 case DRX_STANDARD_ITU_B
:
6462 switch (constellation
) {
6463 case DRX_CONSTELLATION_QAM64
:
6464 fecRsPeriod
= 31581;
6465 fecOcSncFailPeriod
= 17932;
6467 case DRX_CONSTELLATION_QAM256
:
6468 fecRsPeriod
= 45446;
6469 fecOcSncFailPeriod
= 25805;
6472 return (DRX_STS_INVALID_ARG
);
6476 return (DRX_STS_INVALID_ARG
);
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);
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 */
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 */
6501 switch (constellation
) {
6502 case DRX_CONSTELLATION_QAM64
:
6503 /* a(16 bit) * b(4 bit) = 20 bit result => Mult32 not needed */
6505 qamVdBitCnt
* (QAM_TOP_CONSTELLATION_QAM64
+ 1)
6506 * (QAM_TOP_CONSTELLATION_QAM64
+ 1);
6508 case DRX_CONSTELLATION_QAM256
:
6509 /* a(16 bit) * b(5 bit) = 21 bit result => Mult32 not needed */
6511 qamVdBitCnt
* (QAM_TOP_CONSTELLATION_QAM256
+ 1)
6512 * (QAM_TOP_CONSTELLATION_QAM256
+ 1);
6515 return (DRX_STS_INVALID_ARG
);
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;
6523 /* a(16 bit) * b(16 bit) = 32 bit result => Mult32 not needed */
6524 qamVdBitCnt
*= qamVdPeriod
;
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
;
6533 return (DRX_STS_OK
);
6535 return (DRX_STS_ERROR
);
6538 /*============================================================================*/
6541 * \fn DRXStatus_t SetQAM16 ()
6542 * \brief QAM16 specific setup
6543 * \param demod instance of demod.
6544 * \return DRXStatus_t.
6546 static DRXStatus_t
SetQAM16(pDRXDemodInstance_t demod
)
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 */
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 */
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
));
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);
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);
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));
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);
6611 WR16(devAddr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 40960);
6613 return (DRX_STS_OK
);
6615 return (DRX_STS_ERROR
);
6618 /*============================================================================*/
6621 * \fn DRXStatus_t SetQAM32 ()
6622 * \brief QAM32 specific setup
6623 * \param demod instance of demod.
6624 * \return DRXStatus_t.
6626 static DRXStatus_t
SetQAM32(pDRXDemodInstance_t demod
)
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 */
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 */
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
));
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);
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);
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));
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);
6691 WR16(devAddr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 20480);
6693 return (DRX_STS_OK
);
6695 return (DRX_STS_ERROR
);
6698 /*============================================================================*/
6701 * \fn DRXStatus_t SetQAM64 ()
6702 * \brief QAM64 specific setup
6703 * \param demod instance of demod.
6704 * \return DRXStatus_t.
6706 static DRXStatus_t
SetQAM64(pDRXDemodInstance_t demod
)
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 */
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 */
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
));
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);
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);
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));
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);
6771 WR16(devAddr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 43008);
6773 return (DRX_STS_OK
);
6775 return (DRX_STS_ERROR
);
6778 /*============================================================================*/
6781 * \fn DRXStatus_t SetQAM128 ()
6782 * \brief QAM128 specific setup
6783 * \param demod: instance of demod.
6784 * \return DRXStatus_t.
6786 static DRXStatus_t
SetQAM128(pDRXDemodInstance_t demod
)
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 */
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 */
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
));
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);
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);
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));
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);
6851 WR16(devAddr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 20992);
6853 return (DRX_STS_OK
);
6855 return (DRX_STS_ERROR
);
6858 /*============================================================================*/
6861 * \fn DRXStatus_t SetQAM256 ()
6862 * \brief QAM256 specific setup
6863 * \param demod: instance of demod.
6864 * \return DRXStatus_t.
6866 static DRXStatus_t
SetQAM256(pDRXDemodInstance_t demod
)
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 */
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 */
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
));
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);
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);
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));
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);
6931 WR16(devAddr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 43520);
6933 return (DRX_STS_OK
);
6935 return (DRX_STS_ERROR
);
6938 /*============================================================================*/
6939 #define QAM_SET_OP_ALL 0x1
6940 #define QAM_SET_OP_CONSTELLATION 0x2
6941 #define QAM_SET_OP_SPECTRUM 0X4
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.
6951 SetQAM(pDRXDemodInstance_t demod
,
6952 pDRXChannel_t channel
, DRXFrequency_t tunerFreqOffset
, u32_t op
)
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,
6967 /* parameter */ NULL
,
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 */
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 */
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 */
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 */
7091 devAddr
= demod
->myI2CDevAddr
;
7092 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
7093 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
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;
7101 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256
;
7102 channel
->symbolrate
= 5360537;
7103 iqmRcStretch
= IQM_RC_STRETCH_QAM_B_256
;
7105 case DRX_CONSTELLATION_QAM64
:
7106 iqmRcRate
= 0x00C05A0E;
7108 channel
->symbolrate
= 5056941;
7109 iqmRcStretch
= IQM_RC_STRETCH_QAM_B_64
;
7112 return (DRX_STS_INVALID_ARG
);
7115 adcFrequency
= (commonAttr
->sysClockFreq
* 1000) / 3;
7116 CHK_ZERO(channel
->symbolrate
);
7118 (adcFrequency
/ channel
->symbolrate
) * (1 << 21) +
7120 ((adcFrequency
% channel
->symbolrate
),
7121 channel
->symbolrate
) >> 7) - (1 << 23);
7124 (channel
->symbolrate
+
7125 (adcFrequency
>> 13),
7126 adcFrequency
) >> 16);
7127 if (lcSymbolFreq
> 511)
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 */
7146 return (DRX_STS_INVALID_ARG
);
7150 if (op
& QAM_SET_OP_ALL
) {
7152 STEP 1: reset demodulator
7153 resets IQM, QAM and FEC HW blocks
7154 resets SCU variables
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
);
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
));
7174 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
7176 STEP 2: configure demodulator
7178 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
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
));
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
));
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
));
7209 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
7211 WR16(devAddr
, QAM_LC_SYMBOL_FREQ__A
, lcSymbolFreq
);
7212 WR16(devAddr
, IQM_RC_STRETCH__A
, iqmRcStretch
);
7215 if (op
& QAM_SET_OP_ALL
) {
7216 if (extAttr
->hasLNA
== FALSE
) {
7217 WR16(devAddr
, IQM_AF_AMUX__A
, 0x02);
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
);
7223 WR16(devAddr
, SCU_RAM_QAM_WR_RSV_0__A
, 0x5f); /* scu temporary shut down agc */
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);
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 ! */
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 ! */
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 ! */
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);
7257 return (DRX_STS_ERROR
);
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);
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);
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
));
7294 CHK_ERROR(InitAGC(demod
));
7295 CHK_ERROR(SetAgcIf(demod
, &(extAttr
->qamIfAgcCfg
), FALSE
));
7296 CHK_ERROR(SetAgcRf(demod
, &(extAttr
->qamRfAgcCfg
), FALSE
));
7298 /* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
7300 DRXJCfgAfeGain_t qamPgaCfg
= { DRX_STANDARD_ITU_B
, 0 };
7302 qamPgaCfg
.gain
= extAttr
->qamPgaCfg
;
7303 CHK_ERROR(CtrlSetCfgAfeGain(demod
, &qamPgaCfg
));
7305 CHK_ERROR(CtrlSetCfgPreSaw(demod
, &(extAttr
->qamPreSawCfg
)));
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
));
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
));
7331 return (DRX_STS_ERROR
);
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
));
7340 /* SETP 4: constellation specific setup */
7341 switch (channel
->constellation
) {
7342 case DRX_CONSTELLATION_QAM16
:
7343 CHK_ERROR(SetQAM16(demod
));
7345 case DRX_CONSTELLATION_QAM32
:
7346 CHK_ERROR(SetQAM32(demod
));
7348 case DRX_CONSTELLATION_QAM64
:
7349 CHK_ERROR(SetQAM64(demod
));
7351 case DRX_CONSTELLATION_QAM128
:
7352 CHK_ERROR(SetQAM128(demod
));
7354 case DRX_CONSTELLATION_QAM256
:
7355 CHK_ERROR(SetQAM256(demod
));
7358 return (DRX_STS_ERROR
);
7362 if ((op
& QAM_SET_OP_ALL
)) {
7363 WR16(devAddr
, IQM_CF_SCALE_SH__A
, 0);
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
));
7370 /* TODO: move to setStandard after hardware reset value problem is solved */
7371 /* Configure initial MPEG output */
7372 DRXCfgMPEGOutput_t cfgMPEGOutput
;
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
));
7391 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
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
));
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
);
7407 return (DRX_STS_OK
);
7409 return (DRX_STS_ERROR
);
7412 /*============================================================================*/
7414 CtrlGetQAMSigQuality(pDRXDemodInstance_t demod
, pDRXSigQuality_t sigQuality
);
7415 static DRXStatus_t
qamFlipSpec(pDRXDemodInstance_t demod
, pDRXChannel_t channel
)
7417 u32_t iqmFsRateOfs
= 0;
7418 u32_t iqmFsRateLo
= 0;
7419 u16_t qamCtlEna
= 0;
7425 pI2CDeviceAddr_t devAddr
= NULL
;
7426 pDRXJData_t extAttr
= NULL
;
7428 devAddr
= demod
->myI2CDevAddr
;
7429 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
));
7437 /* freeze the frequency control loop */
7438 WR16(devAddr
, QAM_LC_CF__A
, 0);
7439 WR16(devAddr
, QAM_LC_CF1__A
, 0);
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
;
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
);
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);
7459 WR32(devAddr
, IQM_FS_RATE_OFS_LO__A
, iqmFsRateOfs
);
7460 extAttr
->iqmFsRateOfs
= iqmFsRateOfs
;
7461 extAttr
->posImage
= (extAttr
->posImage
) ? FALSE
: TRUE
;
7463 /* freeze dq/fq updating */
7464 RR16(devAddr
, QAM_DQ_MODE__A
, &data
);
7466 data
= (data
& 0xfff9);
7467 WR16(devAddr
, QAM_DQ_MODE__A
, data
);
7468 WR16(devAddr
, QAM_FQ_MODE__A
, data
);
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
);
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
);
7481 WR16(devAddr
, QAM_DQ_MODE__A
, data
);
7482 WR16(devAddr
, QAM_FQ_MODE__A
, data
);
7484 WR16(devAddr
, SCU_RAM_QAM_FSM_STATE_TGT__A
, 4);
7487 while ((fsmState
!= 4) && (i
++ < 100)) {
7488 RR16(devAddr
, SCU_RAM_QAM_FSM_STATE__A
, &fsmState
);
7490 WR16(devAddr
, SCU_RAM_QAM_CTL_ENA__A
, (qamCtlEna
| 0x0016));
7492 return (DRX_STS_OK
);
7494 return (DRX_STS_ERROR
);
7499 #define DEMOD_LOCKED 0x1
7500 #define SYNC_FLIPPED 0x2
7501 #define SPEC_MIRRORED 0x4
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.
7512 QAM64Auto(pDRXDemodInstance_t demod
,
7513 pDRXChannel_t channel
,
7514 DRXFrequency_t tunerFreqOffset
, pDRXLockStatus_t lockStatus
)
7516 DRXSigQuality_t sigQuality
;
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;
7524 /* external attributes for storing aquired channel constellation */
7525 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
7526 *lockStatus
= DRX_NOT_LOCKED
;
7527 startTime
= DRXBSP_HST_Clock();
7530 CHK_ERROR(CtrlLockStatus(demod
, lockStatus
));
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();
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
,
7551 WR16(demod
->myI2CDevAddr
, QAM_SY_TIMEOUT__A
,
7553 state
= SYNC_FLIPPED
;
7554 DRXBSP_HST_Sleep(10);
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);
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
=
7573 } else { /* no need to wait lock */
7576 DRXBSP_HST_Clock() -
7577 DRXJ_QAM_MAX_WAITTIME
- timeoutOfs
;
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 */
7594 DRXBSP_HST_Clock() -
7595 DRXJ_QAM_MAX_WAITTIME
- timeoutOfs
;
7602 DRXBSP_HST_Sleep(10);
7604 ((*lockStatus
!= DRX_LOCKED
) &&
7605 (*lockStatus
!= DRX_NEVER_LOCK
) &&
7606 ((DRXBSP_HST_Clock() - startTime
) <
7607 (DRXJ_QAM_MAX_WAITTIME
+ timeoutOfs
))
7609 /* Returning control to apllication ... */
7611 return (DRX_STS_OK
);
7613 return (DRX_STS_ERROR
);
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.
7626 QAM256Auto(pDRXDemodInstance_t demod
,
7627 pDRXChannel_t channel
,
7628 DRXFrequency_t tunerFreqOffset
, pDRXLockStatus_t lockStatus
)
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
;
7637 /* external attributes for storing aquired channel constellation */
7638 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
7639 *lockStatus
= DRX_NOT_LOCKED
;
7640 startTime
= DRXBSP_HST_Clock();
7643 CHK_ERROR(CtrlLockStatus(demod
, lockStatus
));
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();
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;
7675 DRXBSP_HST_Sleep(10);
7677 ((*lockStatus
< DRX_LOCKED
) &&
7678 (*lockStatus
!= DRX_NEVER_LOCK
) &&
7679 ((DRXBSP_HST_Clock() - startTime
) <
7680 (DRXJ_QAM_MAX_WAITTIME
+ timeoutOfs
)));
7682 return (DRX_STS_OK
);
7684 return (DRX_STS_ERROR
);
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.
7695 SetQAMChannel(pDRXDemodInstance_t demod
,
7696 pDRXChannel_t channel
, DRXFrequency_t tunerFreqOffset
)
7698 DRXLockStatus_t lockStatus
= DRX_NOT_LOCKED
;
7699 pDRXJData_t extAttr
= NULL
;
7700 Bool_t autoFlag
= FALSE
;
7702 /* external attributes for storing aquired channel constellation */
7703 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
;
7716 extAttr
->mirror
= channel
->mirror
;
7719 (demod
, channel
, tunerFreqOffset
, QAM_SET_OP_ALL
));
7721 if ((extAttr
->standard
== DRX_STANDARD_ITU_B
) &&
7722 (channel
->constellation
== DRX_CONSTELLATION_QAM64
)) {
7724 (demod
, channel
, tunerFreqOffset
,
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
,
7736 case DRX_CONSTELLATION_AUTO
: /* for channel scan */
7737 if (extAttr
->standard
== DRX_STANDARD_ITU_B
) {
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
;
7745 extAttr
->mirror
= channel
->mirror
;
7748 (demod
, channel
, tunerFreqOffset
,
7750 CHK_ERROR(QAM256Auto
7751 (demod
, channel
, tunerFreqOffset
,
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
;
7763 extAttr
->mirror
= channel
->mirror
;
7766 u16_t qamCtlEna
= 0;
7767 RR16(demod
->myI2CDevAddr
,
7768 SCU_RAM_QAM_CTL_ENA__A
,
7770 WR16(demod
->myI2CDevAddr
,
7771 SCU_RAM_QAM_CTL_ENA__A
,
7773 ~SCU_RAM_QAM_CTL_ENA_ACQ__M
);
7774 WR16(demod
->myI2CDevAddr
, SCU_RAM_QAM_FSM_STATE_TGT__A
, 0x2); /* force to rate hunting */
7779 QAM_SET_OP_CONSTELLATION
));
7780 WR16(demod
->myI2CDevAddr
,
7781 SCU_RAM_QAM_CTL_ENA__A
, qamCtlEna
);
7784 (demod
, channel
, tunerFreqOffset
,
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
;
7793 if (channel
->mirror
== DRX_MIRROR_AUTO
) {
7794 extAttr
->mirror
= DRX_MIRROR_NO
;
7796 extAttr
->mirror
= channel
->mirror
;
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 */
7808 (demod
, channel
, tunerFreqOffset
,
7809 QAM_SET_OP_CONSTELLATION
));
7810 WR16(demod
->myI2CDevAddr
,
7811 SCU_RAM_QAM_CTL_ENA__A
, qamCtlEna
);
7814 (demod
, channel
, tunerFreqOffset
,
7816 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
7818 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
7819 return (DRX_STS_INVALID_ARG
);
7823 return (DRX_STS_INVALID_ARG
);
7826 return (DRX_STS_OK
);
7828 /* restore starting value */
7830 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
7831 return (DRX_STS_ERROR
);
7834 /*============================================================================*/
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
7841 * precondition: measurement period & measurement prescale must be set
7845 GetQAMRSErrCount(pI2CDeviceAddr_t devAddr
, pDRXJRSErrors_t RSErrors
)
7847 u16_t nrBitErrors
= 0,
7849 nrPacketErrors
= 0, nrFailures
= 0, nrSncParFailCount
= 0;
7851 /* check arguments */
7852 if (devAddr
== NULL
) {
7853 return (DRX_STS_INVALID_ARG
);
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
);
7869 /* These register values are fetched in non-atomic fashion */
7870 /* It is possible that the read values contain unrelated information */
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
;
7879 return (DRX_STS_OK
);
7881 return (DRX_STS_ERROR
);
7884 /*============================================================================*/
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.
7896 * Pre-condition: Device must be started and in lock.
7899 CtrlGetQAMSigQuality(pDRXDemodInstance_t demod
, pDRXSigQuality_t sigQuality
)
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 };
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 */
7930 /* get device basic information */
7931 devAddr
= demod
->myI2CDevAddr
;
7932 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
7933 constellation
= extAttr
->constellation
;
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
);
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
;
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;
7956 case DRX_CONSTELLATION_QAM32
:
7957 qamSlSigPower
= DRXJ_QAM_SL_SIG_POWER_QAM32
<< 2;
7959 case DRX_CONSTELLATION_QAM64
:
7960 qamSlSigPower
= DRXJ_QAM_SL_SIG_POWER_QAM64
<< 2;
7962 case DRX_CONSTELLATION_QAM128
:
7963 qamSlSigPower
= DRXJ_QAM_SL_SIG_POWER_QAM128
<< 2;
7965 case DRX_CONSTELLATION_QAM256
:
7966 qamSlSigPower
= DRXJ_QAM_SL_SIG_POWER_QAM256
<< 2;
7969 return (DRX_STS_ERROR
);
7972 /* ------------------------------ */
7973 /* MER Calculation */
7974 /* ------------------------------ */
7975 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
7977 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
7978 if (qamSlErrPower
== 0)
7982 Log10Times100(qamSlSigPower
) -
7983 Log10Times100((u32_t
) qamSlErrPower
);
7985 /* ----------------------------------------- */
7986 /* Pre Viterbi Symbol Error Rate Calculation */
7987 /* ----------------------------------------- */
7988 /* pre viterbi SER is good if it is bellow 0.025 */
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
;
8000 if ((m
<< e
) >> 3 > 549752) { /* the max of FracTimes1e6 */
8001 qamVDSer
= 500000; /* clip BER 0.5 */
8004 FracTimes1e6(m
<< ((e
> 2) ? (e
- 3) : e
),
8005 vdBitCnt
* ((e
> 2) ? 1 : 8) / 8);
8008 /* --------------------------------------- */
8009 /* pre and post RedSolomon BER Calculation */
8010 /* --------------------------------------- */
8011 /* pre RS BER is good if it is below 3.5e-4 */
8013 /* get the register values */
8014 preBitErrRS
= (u32_t
) measuredRSErrors
.nrBitErrors
;
8015 pktErrs
= postBitErrRS
= (u32_t
) measuredRSErrors
.nrSncParFailCount
;
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
;
8026 /*qamPreRSBer = FracTimes1e6( berCnt, rsBitCnt ); */
8027 if (m
> (rsBitCnt
>> (e
+ 1)) || (rsBitCnt
>> e
) == 0) {
8028 qamPreRSBer
= 500000; /* clip BER 0.5 */
8030 qamPreRSBer
= FracTimes1e6(m
, rsBitCnt
>> e
);
8033 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
8034 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
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
8042 Precision errors still possible.
8044 e
= postBitErrRS
* 742686;
8045 m
= fecOcPeriod
* 100;
8046 if (fecOcPeriod
== 0)
8047 qamPostRSBer
= 0xFFFFFFFF;
8049 qamPostRSBer
= e
/ m
;
8051 /* fill signal quality data structure */
8052 sigQuality
->MER
= ((u16_t
) qamSlMer
);
8053 if (extAttr
->standard
== DRX_STANDARD_ITU_B
) {
8054 sigQuality
->preViterbiBER
= qamVDSer
;
8056 sigQuality
->preViterbiBER
= qamPreRSBer
;
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
));
8064 sigQuality
->packetError
= ((u16_t
) pktErrs
);
8067 return (DRX_STS_OK
);
8069 return (DRX_STS_ERROR
);
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.
8081 CtrlGetQAMConstel(pDRXDemodInstance_t demod
, pDRXComplex_t complexNr
)
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 */
8091 pI2CDeviceAddr_t devAddr
= NULL
;
8092 /**< device address */
8094 /* read device info */
8095 devAddr
= demod
->myI2CDevAddr
;
8098 /* Monitor bus grabbing is an open external interface issue */
8099 /* Needs to be checked when external interface PG is updated */
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
);
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
);
8125 /* Disable MB grabber in the FEC OC */
8126 WR16(devAddr
, FEC_OC_OCR_MODE__A
, 0x00);
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
);
8134 /* interpret data (re & im) according to the Monitor bus mapping ?? */
8136 /* sign extension, 10th bit is sign bit */
8137 if ((re
& 0x0200) == 0x0200) {
8140 if ((im
& 0x0200) == 0x0200) {
8143 complexNr
->re
= ((s16_t
) re
);
8144 complexNr
->im
= ((s16_t
) im
);
8146 /* Restore MB (Monitor bus) */
8147 WR16(devAddr
, QAM_SL_COMM_MB__A
, qamSlCommMbInit
);
8149 return (DRX_STS_OK
);
8151 return (DRX_STS_ERROR
);
8153 #endif /* #ifndef DRXJ_VSB_ONLY */
8155 /*============================================================================*/
8156 /*== END QAM DATAPATH FUNCTIONS ==*/
8157 /*============================================================================*/
8159 /*============================================================================*/
8160 /*============================================================================*/
8161 /*== ATV DATAPATH FUNCTIONS ==*/
8162 /*============================================================================*/
8163 /*============================================================================*/
8166 Implementation notes.
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)
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.
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)
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
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
8195 (Shadow settings will not be used for now, they will be implemented
8196 later on because of the schedule)
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
8211 The "settings" will consist of: AGC settings, filter settings etc.
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.
8219 /* -------------------------------------------------------------------------- */
8222 * \brief Get array index for atv coef (extAttr->atvTopCoefX[index])
8224 * \param pointer to index
8225 * \return DRXStatus_t.
8228 static DRXStatus_t
AtvEquCoefIndex(DRXStandard_t standard
, int *index
)
8231 case DRX_STANDARD_PAL_SECAM_BG
:
8232 *index
= (int)DRXJ_COEF_IDX_BG
;
8234 case DRX_STANDARD_PAL_SECAM_DK
:
8235 *index
= (int)DRXJ_COEF_IDX_DK
;
8237 case DRX_STANDARD_PAL_SECAM_I
:
8238 *index
= (int)DRXJ_COEF_IDX_I
;
8240 case DRX_STANDARD_PAL_SECAM_L
:
8241 *index
= (int)DRXJ_COEF_IDX_L
;
8243 case DRX_STANDARD_PAL_SECAM_LP
:
8244 *index
= (int)DRXJ_COEF_IDX_LP
;
8246 case DRX_STANDARD_NTSC
:
8247 *index
= (int)DRXJ_COEF_IDX_MN
;
8249 case DRX_STANDARD_FM
:
8250 *index
= (int)DRXJ_COEF_IDX_FM
;
8253 *index
= (int)DRXJ_COEF_IDX_MN
; /* still return a valid index */
8254 return DRX_STS_ERROR
;
8261 /* -------------------------------------------------------------------------- */
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.
8271 AtvUpdateConfig(pDRXDemodInstance_t demod
, Bool_t forceUpdate
)
8273 pI2CDeviceAddr_t devAddr
= NULL
;
8274 pDRXJData_t extAttr
= NULL
;
8276 devAddr
= demod
->myI2CDevAddr
;
8277 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
8279 /* equalizer coefficients */
8281 ((extAttr
->atvCfgChangedFlags
& DRXJ_ATV_CHANGED_COEF
) != 0)) {
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
]);
8291 /* bypass fast carrier recovery */
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
;
8300 data
|= IQM_RT_ROT_BP_ROT_OFF_ACTIVE
;
8302 WR16(devAddr
, IQM_RT_ROT_BP__A
, data
);
8305 /* peak filter setting */
8307 ((extAttr
->atvCfgChangedFlags
& DRXJ_ATV_CHANGED_PEAK_FLT
) != 0)) {
8308 WR16(devAddr
, ATV_TOP_VID_PEAK__A
, extAttr
->atvTopVidPeak
);
8311 /* noise filter setting */
8313 ((extAttr
->atvCfgChangedFlags
& DRXJ_ATV_CHANGED_NOISE_FLT
) != 0)) {
8314 WR16(devAddr
, ATV_TOP_NOISE_TH__A
, extAttr
->atvTopNoiseTh
);
8317 /* SIF attenuation */
8319 ((extAttr
->atvCfgChangedFlags
& DRXJ_ATV_CHANGED_SIF_ATT
) != 0)) {
8320 u16_t attenuation
= 0;
8322 switch (extAttr
->sifAttenuation
) {
8323 case DRXJ_SIF_ATTENUATION_0DB
:
8324 attenuation
= ATV_TOP_AF_SIF_ATT_0DB
;
8326 case DRXJ_SIF_ATTENUATION_3DB
:
8327 attenuation
= ATV_TOP_AF_SIF_ATT_M3DB
;
8329 case DRXJ_SIF_ATTENUATION_6DB
:
8330 attenuation
= ATV_TOP_AF_SIF_ATT_M6DB
;
8332 case DRXJ_SIF_ATTENUATION_9DB
:
8333 attenuation
= ATV_TOP_AF_SIF_ATT_M9DB
;
8336 return DRX_STS_ERROR
;
8339 WR16(devAddr
, ATV_TOP_AF_SIF_ATT__A
, attenuation
);
8342 /* SIF & CVBS enable */
8344 ((extAttr
->atvCfgChangedFlags
& DRXJ_ATV_CHANGED_OUTPUT
) != 0)) {
8347 RR16(devAddr
, ATV_TOP_STDBY__A
, &data
);
8348 if (extAttr
->enableCVBSOutput
) {
8349 data
|= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
;
8351 data
&= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
);
8354 if (extAttr
->enableSIFOutput
) {
8355 data
&= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY
);
8357 data
|= ATV_TOP_STDBY_SIF_STDBY_STANDBY
;
8359 WR16(devAddr
, ATV_TOP_STDBY__A
, data
);
8362 extAttr
->atvCfgChangedFlags
= 0;
8364 return (DRX_STS_OK
);
8366 return (DRX_STS_ERROR
);
8369 /* -------------------------------------------------------------------------- */
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.
8379 CtrlSetCfgATVOutput(pDRXDemodInstance_t demod
, pDRXJCfgAtvOutput_t outputCfg
)
8381 pDRXJData_t extAttr
= NULL
;
8383 /* Check arguments */
8384 if (outputCfg
== NULL
) {
8385 return (DRX_STS_INVALID_ARG
);
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
:
8398 return DRX_STS_INVALID_ARG
;
8402 if (extAttr
->sifAttenuation
!= outputCfg
->sifAttenuation
) {
8403 extAttr
->sifAttenuation
= outputCfg
->sifAttenuation
;
8404 extAttr
->atvCfgChangedFlags
|= DRXJ_ATV_CHANGED_SIF_ATT
;
8408 if (extAttr
->enableCVBSOutput
!= outputCfg
->enableCVBSOutput
) {
8409 extAttr
->enableCVBSOutput
= outputCfg
->enableCVBSOutput
;
8410 extAttr
->atvCfgChangedFlags
|= DRXJ_ATV_CHANGED_OUTPUT
;
8413 if (extAttr
->enableSIFOutput
!= outputCfg
->enableSIFOutput
) {
8414 extAttr
->enableSIFOutput
= outputCfg
->enableSIFOutput
;
8415 extAttr
->atvCfgChangedFlags
|= DRXJ_ATV_CHANGED_OUTPUT
;
8418 CHK_ERROR(AtvUpdateConfig(demod
, FALSE
));
8420 return (DRX_STS_OK
);
8422 return (DRX_STS_ERROR
);
8425 /* -------------------------------------------------------------------------- */
8426 #ifndef DRXJ_DIGITAL_ONLY
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.
8436 CtrlSetCfgAtvEquCoef(pDRXDemodInstance_t demod
, pDRXJCfgAtvEquCoef_t coef
)
8438 pDRXJData_t extAttr
= NULL
;
8441 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
8443 /* current standard needs to be an ATV standard */
8444 if (!DRXJ_ISATVSTD(extAttr
->standard
)) {
8445 return DRX_STS_ERROR
;
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
);
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
;
8468 CHK_ERROR(AtvUpdateConfig(demod
, FALSE
));
8470 return (DRX_STS_OK
);
8472 return (DRX_STS_ERROR
);
8475 /* -------------------------------------------------------------------------- */
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.
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
8490 CtrlGetCfgAtvEquCoef(pDRXDemodInstance_t demod
, pDRXJCfgAtvEquCoef_t coef
)
8492 pDRXJData_t extAttr
= NULL
;
8495 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
8497 /* current standard needs to be an ATV standard */
8498 if (!DRXJ_ISATVSTD(extAttr
->standard
)) {
8499 return DRX_STS_ERROR
;
8502 /* Check arguments */
8504 return DRX_STS_INVALID_ARG
;
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
];
8513 return (DRX_STS_OK
);
8515 return (DRX_STS_ERROR
);
8518 /* -------------------------------------------------------------------------- */
8520 * \fn DRXStatus_t CtrlSetCfgAtvMisc()
8521 * \brief Set misc. settings for ATV.
8522 * \param demod instance of demodulator
8524 * \return DRXStatus_t.
8528 CtrlSetCfgAtvMisc(pDRXDemodInstance_t demod
, pDRXJCfgAtvMisc_t settings
)
8530 pDRXJData_t extAttr
= NULL
;
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
);
8540 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
8542 if (settings
->peakFilter
!= extAttr
->atvTopVidPeak
) {
8543 extAttr
->atvTopVidPeak
= settings
->peakFilter
;
8544 extAttr
->atvCfgChangedFlags
|= DRXJ_ATV_CHANGED_PEAK_FLT
;
8547 if (settings
->noiseFilter
!= extAttr
->atvTopNoiseTh
) {
8548 extAttr
->atvTopNoiseTh
= settings
->noiseFilter
;
8549 extAttr
->atvCfgChangedFlags
|= DRXJ_ATV_CHANGED_NOISE_FLT
;
8552 CHK_ERROR(AtvUpdateConfig(demod
, FALSE
));
8554 return (DRX_STS_OK
);
8556 return (DRX_STS_ERROR
);
8559 /* -------------------------------------------------------------------------- */
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.
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
8573 CtrlGetCfgAtvMisc(pDRXDemodInstance_t demod
, pDRXJCfgAtvMisc_t settings
)
8575 pDRXJData_t extAttr
= NULL
;
8577 /* Check arguments */
8578 if (settings
== NULL
) {
8579 return DRX_STS_INVALID_ARG
;
8582 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
8584 settings
->peakFilter
= extAttr
->atvTopVidPeak
;
8585 settings
->noiseFilter
= extAttr
->atvTopNoiseTh
;
8587 return (DRX_STS_OK
);
8590 /* -------------------------------------------------------------------------- */
8592 /* -------------------------------------------------------------------------- */
8594 * \fn DRXStatus_t CtrlGetCfgAtvOutput()
8596 * \param demod instance of demodulator
8597 * \param outputCfg output configuaration
8598 * \return DRXStatus_t.
8602 CtrlGetCfgAtvOutput(pDRXDemodInstance_t demod
, pDRXJCfgAtvOutput_t outputCfg
)
8606 /* Check arguments */
8607 if (outputCfg
== NULL
) {
8608 return DRX_STS_INVALID_ARG
;
8611 RR16(demod
->myI2CDevAddr
, ATV_TOP_STDBY__A
, &data
);
8612 if (data
& ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
) {
8613 outputCfg
->enableCVBSOutput
= TRUE
;
8615 outputCfg
->enableCVBSOutput
= FALSE
;
8618 if (data
& ATV_TOP_STDBY_SIF_STDBY_STANDBY
) {
8619 outputCfg
->enableSIFOutput
= FALSE
;
8621 outputCfg
->enableSIFOutput
= TRUE
;
8622 RR16(demod
->myI2CDevAddr
, ATV_TOP_AF_SIF_ATT__A
, &data
);
8623 outputCfg
->sifAttenuation
= (DRXJSIFAttenuation_t
) data
;
8626 return (DRX_STS_OK
);
8628 return (DRX_STS_ERROR
);
8631 /* -------------------------------------------------------------------------- */
8633 * \fn DRXStatus_t CtrlGetCfgAtvAgcStatus()
8635 * \param demod instance of demodulator
8636 * \param agcStatus agc status
8637 * \return DRXStatus_t.
8641 CtrlGetCfgAtvAgcStatus(pDRXDemodInstance_t demod
,
8642 pDRXJCfgAtvAgcStatus_t agcStatus
)
8644 pI2CDeviceAddr_t devAddr
= NULL
;
8645 pDRXJData_t extAttr
= NULL
;
8649 /* Check arguments */
8650 if (agcStatus
== NULL
) {
8651 return DRX_STS_INVALID_ARG
;
8654 devAddr
= demod
->myI2CDevAddr
;
8655 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
8661 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
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 */
8667 if (tmp
% 1000 >= 500) {
8668 (agcStatus
->rfAgcGain
)++;
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
8675 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
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 */
8681 if (tmp
% 1000 >= 500) {
8682 (agcStatus
->ifAgcGain
)++;
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)
8693 SARR16(devAddr
, SCU_RAM_ATV_VID_GAIN_HI__A
, &data
);
8694 /* dividing by 32 inclusive rounding */
8696 if ((data
& 1) != 0) {
8700 agcStatus
->videoAgcGain
= ((s16_t
) data
) - 75; /* 0.1 dB */
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)
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) {
8717 agcStatus
->audioAgcGain
= ((s16_t
) data
) - 4; /* 0.1 dB */
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
);
8728 return (DRX_STS_OK
);
8730 return (DRX_STS_ERROR
);
8733 /* -------------------------------------------------------------------------- */
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.
8742 * * Starts ATV and IQM
8743 * * AUdio already started during standard init for ATV.
8745 static DRXStatus_t
PowerUpATV(pDRXDemodInstance_t demod
, DRXStandard_t standard
)
8747 pI2CDeviceAddr_t devAddr
= NULL
;
8748 pDRXJData_t extAttr
= NULL
;
8750 devAddr
= demod
->myI2CDevAddr
;
8751 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
));
8759 WR16(devAddr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_ACTIVE
);
8761 /* Audio, already done during set standard */
8763 return (DRX_STS_OK
);
8765 return (DRX_STS_ERROR
);
8767 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
8769 /* -------------------------------------------------------------------------- */
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.
8778 * Stops and thus resets ATV and IQM block
8779 * SIF and CVBS ADC are powered down
8780 * Calls audio power down
8783 PowerDownATV(pDRXDemodInstance_t demod
, DRXStandard_t standard
, Bool_t primary
)
8785 pI2CDeviceAddr_t devAddr
= NULL
;
8786 DRXJSCUCmd_t cmdSCU
= { /* command */ 0,
8787 /* parameterLen */ 0,
8789 /* *parameter */ NULL
,
8792 u16_t cmdResult
= 0;
8793 pDRXJData_t extAttr
= NULL
;
8795 devAddr
= demod
->myI2CDevAddr
;
8796 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
)));
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
));
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
);
8822 CHK_ERROR(PowerDownAud(demod
));
8824 return (DRX_STS_OK
);
8826 return (DRX_STS_ERROR
);
8829 /* -------------------------------------------------------------------------- */
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.
8837 * Init all channel independent registers.
8838 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
8841 #ifndef DRXJ_DIGITAL_ONLY
8842 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
8844 SetATVStandard(pDRXDemodInstance_t demod
, pDRXStandard_t standard
)
8846 /* TODO: enable alternative for tap settings via external file
8849 #ifdef DRXJ_ATV_COEF_FILE
8850 #include DRXJ_ATV_COEF_FILE
8852 ... code defining fixed coef's ...
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".
8859 Still to check if this will work; DRXJ_16TO8 macro may cause
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
9103 pI2CDeviceAddr_t devAddr
= NULL
;
9104 DRXJSCUCmd_t cmdSCU
= { /* command */ 0,
9105 /* parameterLen */ 0,
9107 /* *parameter */ NULL
,
9110 u16_t cmdResult
= 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
;
9118 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9119 devAddr
= demod
->myI2CDevAddr
;
9121 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
9122 commonAttr
= demod
->myCommonAttr
;
9124 /* Check if audio microcode is already uploaded */
9125 if (!(extAttr
->flagAudMcUploaded
)) {
9126 ucodeInfo
.mcData
= commonAttr
->microcode
;
9127 ucodeInfo
.mcSize
= commonAttr
->microcodeSize
;
9129 /* Upload only audio microcode */
9130 CHK_ERROR(CtrlUCodeUpload
9131 (demod
, &ucodeInfo
, UCODE_UPLOAD
, TRUE
));
9133 if (commonAttr
->verifyMicrocode
== TRUE
) {
9134 CHK_ERROR(CtrlUCodeUpload
9135 (demod
, &ucodeInfo
, UCODE_VERIFY
, TRUE
));
9138 /* Prevent uploading audio microcode again */
9139 extAttr
->flagAudMcUploaded
= TRUE
;
9141 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
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
);
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
));
9158 WR16(devAddr
, ATV_TOP_MOD_CONTROL__A
, ATV_TOP_MOD_CONTROL__PRE
);
9160 /* TODO remove AUTO/OFF patches after ucode fix. */
9161 switch (*standard
) {
9162 case DRX_STANDARD_NTSC
:
9164 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_MN
;
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
));
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
);
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
;
9192 case DRX_STANDARD_FM
:
9194 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_FM
;
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);
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
;
9214 case DRX_STANDARD_PAL_SECAM_BG
:
9216 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_B
;
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
;
9243 case DRX_STANDARD_PAL_SECAM_DK
:
9245 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_DK
;
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
;
9272 case DRX_STANDARD_PAL_SECAM_I
:
9274 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_I
;
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
;
9301 case DRX_STANDARD_PAL_SECAM_L
:
9302 /* PAL/SECAM L with negative modulation */
9303 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_L
;
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
;
9332 case DRX_STANDARD_PAL_SECAM_LP
:
9333 /* PAL/SECAM L with positive modulation */
9334 cmdParam
= SCU_RAM_ATV_STANDARD_STANDARD_LP
;
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
;
9364 return (DRX_STS_ERROR
);
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);
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);
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
);
9384 WR16(devAddr
, IQM_RT_ACTIVE__A
, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON
|
9385 IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON
);
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
);
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);
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);
9411 /* Override reset values with current shadow settings */
9412 CHK_ERROR(AtvUpdateConfig(demod
, TRUE
));
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
)));
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
));
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);
9433 WR16(devAddr
, SCU_RAM_ATV_ENABLE_IIR_WA__A
, 1);
9434 WR16(devAddr
, SCU_RAM_ATV_IIR_CRIT__A
, 225);
9437 return (DRX_STS_OK
);
9439 return (DRX_STS_ERROR
);
9443 /* -------------------------------------------------------------------------- */
9445 #ifndef DRXJ_DIGITAL_ONLY
9447 * \fn DRXStatus_t SetATVChannel ()
9448 * \brief Set ATV channel.
9449 * \param demod: instance of demod.
9450 * \return DRXStatus_t.
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.
9459 SetATVChannel(pDRXDemodInstance_t demod
,
9460 DRXFrequency_t tunerFreqOffset
,
9461 pDRXChannel_t channel
, DRXStandard_t standard
)
9463 DRXJSCUCmd_t cmdSCU
= { /* command */ 0,
9464 /* parameterLen */ 0,
9466 /* parameter */ NULL
,
9469 u16_t cmdResult
= 0;
9470 pDRXJData_t extAttr
= NULL
;
9471 pI2CDeviceAddr_t devAddr
= NULL
;
9473 devAddr
= demod
->myI2CDevAddr
;
9474 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9477 Program frequency shifter
9478 No need to account for mirroring on RF
9480 if (channel
->mirror
== DRX_MIRROR_AUTO
) {
9481 extAttr
->mirror
= DRX_MIRROR_NO
;
9483 extAttr
->mirror
= channel
->mirror
;
9486 CHK_ERROR(SetFrequency(demod
, channel
, tunerFreqOffset
));
9487 WR16(devAddr
, ATV_TOP_CR_FREQ__A
, ATV_TOP_CR_FREQ__PRE
);
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
));
9498 /* if ( (extAttr->standard == DRX_STANDARD_FM) && (extAttr->flagSetAUDdone == TRUE) )
9500 extAttr->detectedRDS = (Bool_t)FALSE;
9503 return (DRX_STS_OK
);
9505 return (DRX_STS_ERROR
);
9509 /* -------------------------------------------------------------------------- */
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.
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.
9524 #ifndef DRXJ_DIGITAL_ONLY
9526 GetATVChannel(pDRXDemodInstance_t demod
,
9527 pDRXChannel_t channel
, DRXStandard_t standard
)
9529 DRXFrequency_t offset
= 0;
9530 pI2CDeviceAddr_t devAddr
= NULL
;
9531 pDRXJData_t extAttr
= NULL
;
9533 devAddr
= demod
->myI2CDevAddr
;
9534 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9537 channel
->bandwidth
= ((pDRXJData_t
) demod
->myExtAttr
)->currBandwidth
;
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
:
9546 u16_t measuredOffset
= 0;
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;
9556 (DRXFrequency_t
) (((s16_t
) measuredOffset
) * 10);
9559 case DRX_STANDARD_PAL_SECAM_LP
:
9561 u16_t measuredOffset
= 0;
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;
9571 (DRXFrequency_t
) (((s16_t
) measuredOffset
) * 10);
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.
9578 /* No bandwidth know for FM */
9579 channel
->bandwidth
= DRX_BANDWIDTH_UNKNOWN
;
9582 return (DRX_STS_ERROR
);
9585 channel
->frequency
-= offset
;
9587 return (DRX_STS_OK
);
9589 return (DRX_STS_ERROR
);
9592 /* -------------------------------------------------------------------------- */
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.
9602 * Taking into account:
9604 * * IF gain (not implemented yet, waiting for IF gain control by ucode)
9607 * All weights (digital, if, rf) must add up to 100.
9609 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
9613 GetAtvSigStrength(pDRXDemodInstance_t demod
, pu16_t sigStrength
)
9615 pI2CDeviceAddr_t devAddr
= NULL
;
9616 pDRXJData_t extAttr
= NULL
;
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 */
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;
9634 u32_t digitalStrength
= 0; /* 0.. 100 */
9635 u32_t rfStrength
= 0; /* 0.. 100 */
9636 u32_t ifStrength
= 0; /* 0.. 100 */
9638 devAddr
= demod
->myI2CDevAddr
;
9639 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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 */
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 */
9660 return (DRX_STS_ERROR
);
9663 RR16(devAddr
, IQM_AF_AGC_RF__A
, &rfCurrGain
);
9664 RR16(devAddr
, IQM_AF_AGC_IF__A
, &ifCurrGain
);
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
;
9680 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
9681 of clipping at ADC */
9683 /* Compute signal strength (in %) per "gain domain" */
9686 /* TODO: ADC clipping not handled */
9687 digitalStrength
= (100 * (digitalMaxGain
- (u32_t
) digitalCurrGain
)) /
9688 (digitalMaxGain
- digitalMinGain
);
9690 /* TODO: IF gain not implemented yet in microcode, check after impl. */
9691 ifStrength
= (100 * ((u32_t
) ifCurrGain
- ifMaxGain
)) /
9692 (ifMinGain
- ifMaxGain
);
9695 /* TODO: ADC clipping not handled */
9696 rfStrength
= (100 * ((u32_t
) rfCurrGain
- rfMaxGain
)) /
9697 (rfMinGain
- rfMaxGain
);
9699 /* Compute a weighted signal strength (in %) */
9700 *sigStrength
= (u16_t
) (digitalWeight
* digitalStrength
+
9701 rfWeight
* rfStrength
+ ifWeight
* ifStrength
);
9702 *sigStrength
/= 100;
9704 return (DRX_STS_OK
);
9706 return (DRX_STS_ERROR
);
9709 /* -------------------------------------------------------------------------- */
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.
9722 AtvSigQuality(pDRXDemodInstance_t demod
, pDRXSigQuality_t sigQuality
)
9724 pI2CDeviceAddr_t devAddr
= NULL
;
9725 u16_t qualityIndicator
= 0;
9727 devAddr
= demod
->myI2CDevAddr
;
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;
9739 0x000..0x080: strong signal => 80% .. 100%
9740 0x080..0x700: weak signal => 30% .. 80%
9741 0x700..0x7ff: no signal => 0% .. 30%
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));
9753 sigQuality
->indicator
=
9754 (30 * (0x7FF - qualityIndicator
)) / (0x7FF - 0x701);
9757 return (DRX_STS_OK
);
9759 return (DRX_STS_ERROR
);
9761 #endif /* DRXJ_DIGITAL_ONLY */
9763 /*============================================================================*/
9764 /*== END ATV DATAPATH FUNCTIONS ==*/
9765 /*============================================================================*/
9767 #ifndef DRXJ_EXCLUDE_AUDIO
9768 /*===========================================================================*/
9769 /*===========================================================================*/
9770 /*== AUDIO DATAPATH FUNCTIONS ==*/
9771 /*===========================================================================*/
9772 /*===========================================================================*/
9775 * \brief Power up AUD.
9776 * \param demod instance of demodulator
9777 * \return DRXStatus_t.
9780 static DRXStatus_t
PowerUpAud(pDRXDemodInstance_t demod
, Bool_t setStandard
)
9782 DRXAudStandard_t audStandard
= DRX_AUD_STANDARD_AUTO
;
9783 pI2CDeviceAddr_t devAddr
= NULL
;
9785 devAddr
= demod
->myI2CDevAddr
;
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
);
9792 if (setStandard
== TRUE
) {
9793 CHK_ERROR(AUDCtrlSetStandard(demod
, &audStandard
));
9798 return DRX_STS_ERROR
;
9801 /*============================================================================*/
9804 * \brief Power up AUD.
9805 * \param demod instance of demodulator
9806 * \return DRXStatus_t.
9809 static DRXStatus_t
PowerDownAud(pDRXDemodInstance_t demod
)
9811 pI2CDeviceAddr_t devAddr
= NULL
;
9812 pDRXJData_t extAttr
= NULL
;
9814 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
9815 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9817 WR16(devAddr
, AUD_COMM_EXEC__A
, AUD_COMM_EXEC_STOP
);
9819 extAttr
->audData
.audioIsActive
= FALSE
;
9823 return DRX_STS_ERROR
;
9826 /*============================================================================*/
9828 * \brief Get Modus data from audio RAM
9829 * \param demod instance of demodulator
9830 * \param pointer to modus
9831 * \return DRXStatus_t.
9834 static DRXStatus_t
AUDGetModus(pDRXDemodInstance_t demod
, pu16_t modus
)
9836 pI2CDeviceAddr_t devAddr
= NULL
;
9837 pDRXJData_t extAttr
= NULL
;
9843 if (modus
== NULL
) {
9844 return DRX_STS_INVALID_ARG
;
9847 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
9848 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9851 if (extAttr
->audData
.audioIsActive
== FALSE
) {
9852 CHK_ERROR(PowerUpAud(demod
, TRUE
));
9853 extAttr
->audData
.audioIsActive
= TRUE
;
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
);
9860 rModus
= ((rModusHi
<< 12) & AUD_DEM_RAM_MODUS_HI__M
)
9861 | (((rModusLo
& AUD_DEM_RAM_MODUS_LO__M
)));
9867 return DRX_STS_ERROR
;
9871 /*============================================================================*/
9873 * \brief Get audio RDS dat
9874 * \param demod instance of demodulator
9875 * \param pointer to DRXCfgAudRDS_t
9876 * \return DRXStatus_t.
9880 AUDCtrlGetCfgRDS(pDRXDemodInstance_t demod
, pDRXCfgAudRDS_t status
)
9882 pI2CDeviceAddr_t addr
= NULL
;
9883 pDRXJData_t extAttr
= NULL
;
9885 u16_t rRDSArrayCntInit
= 0;
9886 u16_t rRDSArrayCntCheck
= 0;
9888 u16_t RDSDataCnt
= 0;
9890 addr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
9891 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9893 if (status
== NULL
) {
9894 return DRX_STS_INVALID_ARG
;
9898 if (extAttr
->audData
.audioIsActive
== FALSE
) {
9899 CHK_ERROR(PowerUpAud(demod
, TRUE
));
9900 extAttr
->audData
.audioIsActive
= TRUE
;
9903 status
->valid
= FALSE
;
9905 RR16(addr
, AUD_DEM_RD_RDS_ARRAY_CNT__A
, &rRDSArrayCntInit
);
9907 if (rRDSArrayCntInit
==
9908 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID
) {
9913 if (extAttr
->audData
.rdsDataCounter
== rRDSArrayCntInit
) {
9918 /* RDS is detected, as long as FM radio is selected assume
9919 RDS will be available */
9920 extAttr
->audData
.rdsDataPresent
= TRUE
;
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
;
9929 RR16(addr
, AUD_DEM_RD_RDS_ARRAY_CNT__A
, &rRDSArrayCntCheck
);
9931 if (rRDSArrayCntCheck
== rRDSArrayCntInit
) {
9932 status
->valid
= TRUE
;
9933 extAttr
->audData
.rdsDataCounter
= rRDSArrayCntCheck
;
9938 return DRX_STS_ERROR
;
9941 /*============================================================================*/
9943 * \brief Get the current audio carrier detection status
9944 * \param demod instance of demodulator
9945 * \param pointer to AUDCtrlGetStatus
9946 * \return DRXStatus_t.
9950 AUDCtrlGetCarrierDetectStatus(pDRXDemodInstance_t demod
, pDRXAudStatus_t status
)
9952 pDRXJData_t extAttr
= NULL
;
9953 pI2CDeviceAddr_t devAddr
= NULL
;
9957 if (status
== NULL
) {
9958 return DRX_STS_INVALID_ARG
;
9961 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
9962 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
9965 if (extAttr
->audData
.audioIsActive
== FALSE
) {
9966 CHK_ERROR(PowerUpAud(demod
, TRUE
));
9967 extAttr
->audData
.audioIsActive
= TRUE
;
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
;
9977 /* read stereo sound mode indication */
9978 RR16(devAddr
, AUD_DEM_RD_STATUS__A
, &rData
);
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
;
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
;
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
;
9998 status
->nicamStatus
= DRX_AUD_NICAM_BAD
;
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
;
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
;
10016 return DRX_STS_ERROR
;
10019 /*============================================================================*/
10021 * \brief Get the current audio status parameters
10022 * \param demod instance of demodulator
10023 * \param pointer to AUDCtrlGetStatus
10024 * \return DRXStatus_t.
10028 AUDCtrlGetStatus(pDRXDemodInstance_t demod
, pDRXAudStatus_t status
)
10030 pDRXJData_t extAttr
= NULL
;
10031 pI2CDeviceAddr_t devAddr
= NULL
;
10032 DRXCfgAudRDS_t rds
= { FALSE
, {0} };
10035 if (status
== NULL
) {
10036 return DRX_STS_INVALID_ARG
;
10039 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
10040 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10042 /* carrier detection */
10043 CHK_ERROR(AUDCtrlGetCarrierDetectStatus(demod
, status
));
10046 status
->rds
= FALSE
;
10047 CHK_ERROR(AUDCtrlGetCfgRDS(demod
, &rds
));
10048 status
->rds
= extAttr
->audData
.rdsDataPresent
;
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
;
10057 return DRX_STS_ERROR
;
10060 /*============================================================================*/
10062 * \brief Get the current volume settings
10063 * \param demod instance of demodulator
10064 * \param pointer to DRXCfgAudVolume_t
10065 * \return DRXStatus_t.
10069 AUDCtrlGetCfgVolume(pDRXDemodInstance_t demod
, pDRXCfgAudVolume_t volume
)
10071 pI2CDeviceAddr_t devAddr
= NULL
;
10072 pDRXJData_t extAttr
= NULL
;
10076 u16_t rStrengthLeft
= 0;
10077 u16_t rStrengthRight
= 0;
10079 if (volume
== NULL
) {
10080 return DRX_STS_INVALID_ARG
;
10083 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
10084 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10087 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10088 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10089 extAttr
->audData
.audioIsActive
= TRUE
;
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
;
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
;
10106 if (volume
->volume
> AUD_VOLUME_DB_MAX
) {
10107 volume
->volume
= AUD_VOLUME_DB_MAX
;
10111 /* automatic volume control */
10112 RR16(devAddr
, AUD_DSP_WR_AVC__A
, &rAVC
);
10114 if ((rAVC
& AUD_DSP_WR_AVC_AVC_ON__M
) == AUD_DSP_WR_AVC_AVC_ON_OFF
)
10116 volume
->avcMode
= DRX_AUD_AVC_OFF
;
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
;
10122 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC
:
10123 volume
->avcMode
= DRX_AUD_AVC_DECAYTIME_8S
;
10125 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC
:
10126 volume
->avcMode
= DRX_AUD_AVC_DECAYTIME_4S
;
10128 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC
:
10129 volume
->avcMode
= DRX_AUD_AVC_DECAYTIME_2S
;
10132 return DRX_STS_ERROR
;
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
;
10142 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB
:
10143 volume
->avcMaxAtten
= DRX_AUD_AVC_MAX_ATTEN_18DB
;
10145 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB
:
10146 volume
->avcMaxAtten
= DRX_AUD_AVC_MAX_ATTEN_24DB
;
10149 return DRX_STS_ERROR
;
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
;
10158 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB
:
10159 volume
->avcMaxGain
= DRX_AUD_AVC_MAX_GAIN_6DB
;
10161 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB
:
10162 volume
->avcMaxGain
= DRX_AUD_AVC_MAX_GAIN_12DB
;
10165 return DRX_STS_ERROR
;
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
);
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) */
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;
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;
10191 return DRX_STS_ERROR
;
10194 /*============================================================================*/
10196 * \brief Set the current volume settings
10197 * \param demod instance of demodulator
10198 * \param pointer to DRXCfgAudVolume_t
10199 * \return DRXStatus_t.
10203 AUDCtrlSetCfgVolume(pDRXDemodInstance_t demod
, pDRXCfgAudVolume_t volume
)
10205 pI2CDeviceAddr_t devAddr
= NULL
;
10206 pDRXJData_t extAttr
= NULL
;
10211 if (volume
== NULL
) {
10212 return DRX_STS_INVALID_ARG
;
10215 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
10216 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10219 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10220 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10221 extAttr
->audData
.audioIsActive
= TRUE
;
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
;
10231 RR16(devAddr
, AUD_DSP_WR_VOLUME__A
, &wVolume
);
10233 /* clear the volume mask */
10234 wVolume
&= (u16_t
) ~ AUD_DSP_WR_VOLUME_VOL_MAIN__M
;
10235 if (volume
->mute
== TRUE
) {
10237 /* mute overrules volume */
10238 wVolume
|= (u16_t
) (0);
10241 wVolume
|= (u16_t
) ((volume
->volume
+ AUD_VOLUME_ZERO_DB
) <<
10242 AUD_DSP_WR_VOLUME_VOL_MAIN__B
);
10245 WR16(devAddr
, AUD_DSP_WR_VOLUME__A
, wVolume
);
10247 /* automatic volume control */
10248 RR16(devAddr
, AUD_DSP_WR_AVC__A
, &wAVC
);
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
;
10254 if (volume
->avcMode
== DRX_AUD_AVC_OFF
) {
10255 wAVC
|= (AUD_DSP_WR_AVC_AVC_ON_OFF
);
10258 wAVC
|= (AUD_DSP_WR_AVC_AVC_ON_ON
);
10261 switch (volume
->avcMode
) {
10262 case DRX_AUD_AVC_DECAYTIME_20MS
:
10263 wAVC
|= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC
;
10265 case DRX_AUD_AVC_DECAYTIME_8S
:
10266 wAVC
|= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC
;
10268 case DRX_AUD_AVC_DECAYTIME_4S
:
10269 wAVC
|= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC
;
10271 case DRX_AUD_AVC_DECAYTIME_2S
:
10272 wAVC
|= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC
;
10275 return DRX_STS_INVALID_ARG
;
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
;
10285 case DRX_AUD_AVC_MAX_ATTEN_18DB
:
10286 wAVC
|= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB
;
10288 case DRX_AUD_AVC_MAX_ATTEN_24DB
:
10289 wAVC
|= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB
;
10292 return DRX_STS_INVALID_ARG
;
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
;
10301 case DRX_AUD_AVC_MAX_GAIN_6DB
:
10302 wAVC
|= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB
;
10304 case DRX_AUD_AVC_MAX_GAIN_12DB
:
10305 wAVC
|= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB
;
10308 return DRX_STS_INVALID_ARG
;
10311 /* avc reference level */
10312 if (volume
->avcRefLevel
> AUD_MAX_AVC_REF_LEVEL
) {
10313 return DRX_STS_INVALID_ARG
;
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
);
10319 WR16(devAddr
, AUD_DSP_WR_AVC__A
, wAVC
);
10321 /* all done, store config in data structure */
10322 extAttr
->audData
.volume
= *volume
;
10326 return DRX_STS_ERROR
;
10329 /*============================================================================*/
10331 * \brief Get the I2S settings
10332 * \param demod instance of demodulator
10333 * \param pointer to DRXCfgI2SOutput_t
10334 * \return DRXStatus_t.
10338 AUDCtrlGetCfgOutputI2S(pDRXDemodInstance_t demod
, pDRXCfgI2SOutput_t output
)
10340 pI2CDeviceAddr_t devAddr
= NULL
;
10341 pDRXJData_t extAttr
= NULL
;
10343 u16_t wI2SConfig
= 0;
10344 u16_t rI2SFreq
= 0;
10346 if (output
== NULL
) {
10347 return DRX_STS_INVALID_ARG
;
10350 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
10351 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10354 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10355 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10356 extAttr
->audData
.audioIsActive
= TRUE
;
10359 RR16(devAddr
, AUD_DEM_RAM_I2S_CONFIG2__A
, &wI2SConfig
);
10360 RR16(devAddr
, AUD_DSP_WR_I2S_OUT_FS__A
, &rI2SFreq
);
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
;
10367 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE
:
10368 output
->mode
= DRX_I2S_MODE_SLAVE
;
10371 return DRX_STS_ERROR
;
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
;
10379 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY
:
10380 output
->format
= DRX_I2S_FORMAT_WS_WITH_DATA
;
10383 return DRX_STS_ERROR
;
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
;
10391 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32
:
10392 output
->wordLength
= DRX_I2S_WORDLENGTH_32
;
10395 return DRX_STS_ERROR
;
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
;
10403 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW
:
10404 output
->polarity
= DRX_I2S_POLARITY_RIGHT
;
10407 return DRX_STS_ERROR
;
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
;
10415 output
->outputEnable
= FALSE
;
10418 if (rI2SFreq
> 0) {
10419 output
->frequency
= 6144UL * 48000 / rI2SFreq
;
10420 if (output
->wordLength
== DRX_I2S_WORDLENGTH_16
) {
10421 output
->frequency
*= 2;
10424 output
->frequency
= AUD_I2S_FREQUENCY_MAX
;
10429 return DRX_STS_ERROR
;
10432 /*============================================================================*/
10434 * \brief Set the I2S settings
10435 * \param demod instance of demodulator
10436 * \param pointer to DRXCfgI2SOutput_t
10437 * \return DRXStatus_t.
10441 AUDCtrlSetCfgOutputI2S(pDRXDemodInstance_t demod
, pDRXCfgI2SOutput_t output
)
10443 pI2CDeviceAddr_t devAddr
= NULL
;
10444 pDRXJData_t extAttr
= NULL
;
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;
10452 if (output
== NULL
) {
10453 return DRX_STS_INVALID_ARG
;
10456 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
10457 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10460 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10461 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10462 extAttr
->audData
.audioIsActive
= TRUE
;
10465 RR16(devAddr
, AUD_DEM_RAM_I2S_CONFIG2__A
, &wI2SConfig
);
10468 wI2SConfig
&= (u16_t
) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M
;
10470 switch (output
->mode
) {
10471 case DRX_I2S_MODE_MASTER
:
10472 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER
;
10474 case DRX_I2S_MODE_SLAVE
:
10475 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE
;
10478 return DRX_STS_INVALID_ARG
;
10482 wI2SConfig
&= (u16_t
) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M
;
10484 switch (output
->format
) {
10485 case DRX_I2S_FORMAT_WS_ADVANCED
:
10486 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY
;
10488 case DRX_I2S_FORMAT_WS_WITH_DATA
:
10489 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY
;
10492 return DRX_STS_INVALID_ARG
;
10495 /* I2S word length */
10496 wI2SConfig
&= (u16_t
) ~ AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M
;
10498 switch (output
->wordLength
) {
10499 case DRX_I2S_WORDLENGTH_16
:
10500 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16
;
10502 case DRX_I2S_WORDLENGTH_32
:
10503 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32
;
10506 return DRX_STS_INVALID_ARG
;
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
;
10515 case DRX_I2S_POLARITY_RIGHT
:
10516 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW
;
10519 return DRX_STS_INVALID_ARG
;
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
;
10527 wI2SConfig
|= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE
;
10533 wI2SFreq = 6144 * 48000 * nrbits / ( 32 * frequency )
10535 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
10536 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
10538 if ((output
->frequency
> AUD_I2S_FREQUENCY_MAX
) ||
10539 output
->frequency
< AUD_I2S_FREQUENCY_MIN
) {
10540 return DRX_STS_INVALID_ARG
;
10543 wI2SFreq
= (6144UL * 48000UL) + (output
->frequency
>> 1);
10544 wI2SFreq
/= output
->frequency
;
10546 if (output
->wordLength
== DRX_I2S_WORDLENGTH_16
) {
10550 WR16(devAddr
, AUD_DEM_WR_I2S_CONFIG2__A
, wI2SConfig
);
10551 WR16(devAddr
, AUD_DSP_WR_I2S_OUT_FS__A
, (u16_t
) wI2SFreq
);
10553 /* configure I2S output pads for master or slave mode */
10554 WR16(devAddr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
);
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
;
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
;
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
);
10576 WR16(devAddr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY__PRE
);
10578 /* all done, store config in data structure */
10579 extAttr
->audData
.i2sdata
= *output
;
10583 return DRX_STS_ERROR
;
10586 /*============================================================================*/
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.
10596 AUDCtrlGetCfgAutoSound(pDRXDemodInstance_t demod
,
10597 pDRXCfgAudAutoSound_t autoSound
)
10599 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10600 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10604 if (autoSound
== NULL
) {
10605 return DRX_STS_INVALID_ARG
;
10608 devAddr
= demod
->myI2CDevAddr
;
10609 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10612 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10613 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10614 extAttr
->audData
.audioIsActive
= TRUE
;
10617 CHK_ERROR(AUDGetModus(demod
, &rModus
));
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
:
10624 DRX_AUD_AUTO_SOUND_OFF
;
10626 case AUD_DEM_WR_MODUS_MOD_ASS_ON
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED
:
10628 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON
;
10630 case AUD_DEM_WR_MODUS_MOD_ASS_ON
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED
:
10632 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF
;
10635 return DRX_STS_ERROR
;
10640 return DRX_STS_ERROR
;
10643 /*============================================================================*/
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.
10653 AUDCtrSetlCfgAutoSound(pDRXDemodInstance_t demod
,
10654 pDRXCfgAudAutoSound_t autoSound
)
10656 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10657 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10662 if (autoSound
== NULL
) {
10663 return DRX_STS_INVALID_ARG
;
10666 devAddr
= demod
->myI2CDevAddr
;
10667 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10670 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10671 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10672 extAttr
->audData
.audioIsActive
= TRUE
;
10675 CHK_ERROR(AUDGetModus(demod
, &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
;
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
;
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
;
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
;
10696 return DRX_STS_INVALID_ARG
;
10699 if (wModus
!= rModus
) {
10700 WR16(devAddr
, AUD_DEM_WR_MODUS__A
, wModus
);
10702 /* copy to data structure */
10703 extAttr
->audData
.autoSound
= *autoSound
;
10707 return DRX_STS_ERROR
;
10710 /*============================================================================*/
10712 * \brief Get the Automatic Standard Select thresholds
10713 * \param demod instance of demodulator
10714 * \param pointer to pDRXAudASSThres_t
10715 * \return DRXStatus_t.
10719 AUDCtrlGetCfgASSThres(pDRXDemodInstance_t demod
, pDRXCfgAudASSThres_t thres
)
10721 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10722 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10725 u16_t thresBtsc
= 0;
10726 u16_t thresNicam
= 0;
10728 if (thres
== NULL
) {
10729 return DRX_STS_INVALID_ARG
;
10732 devAddr
= demod
->myI2CDevAddr
;
10733 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10736 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10737 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10738 extAttr
->audData
.audioIsActive
= TRUE
;
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
);
10745 thres
->a2
= thresA2
;
10746 thres
->btsc
= thresBtsc
;
10747 thres
->nicam
= thresNicam
;
10751 return DRX_STS_ERROR
;
10754 /*============================================================================*/
10756 * \brief Get the Automatic Standard Select thresholds
10757 * \param demod instance of demodulator
10758 * \param pointer to pDRXAudASSThres_t
10759 * \return DRXStatus_t.
10763 AUDCtrlSetCfgASSThres(pDRXDemodInstance_t demod
, pDRXCfgAudASSThres_t thres
)
10765 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10766 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10768 if (thres
== NULL
) {
10769 return DRX_STS_INVALID_ARG
;
10772 devAddr
= demod
->myI2CDevAddr
;
10773 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10776 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10777 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10778 extAttr
->audData
.audioIsActive
= TRUE
;
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
);
10785 /* update DRXK data structure with hardware values */
10786 extAttr
->audData
.assThresholds
= *thres
;
10790 return DRX_STS_ERROR
;
10793 /*============================================================================*/
10795 * \brief Get Audio Carrier settings
10796 * \param demod instance of demodulator
10797 * \param pointer to pDRXAudCarrier_t
10798 * \return DRXStatus_t.
10802 AUDCtrlGetCfgCarrier(pDRXDemodInstance_t demod
, pDRXCfgAudCarriers_t carriers
)
10804 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10805 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10823 if (carriers
== NULL
) {
10824 return DRX_STS_INVALID_ARG
;
10827 devAddr
= demod
->myI2CDevAddr
;
10828 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10831 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10832 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10833 extAttr
->audData
.audioIsActive
= TRUE
;
10836 CHK_ERROR(AUDGetModus(demod
, &wModus
));
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
;
10843 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE
:
10844 carriers
->a
.opt
= DRX_NO_CARRIER_NOISE
;
10847 return DRX_STS_ERROR
;
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
;
10856 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE
:
10857 carriers
->b
.opt
= DRX_NO_CARRIER_NOISE
;
10860 return DRX_STS_ERROR
;
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
);
10870 valA
= (((u32_t
) dcoAHi
) << 12) | ((u32_t
) dcoALo
& 0xFFF);
10871 valB
= (((u32_t
) dcoBHi
) << 12) | ((u32_t
) dcoBLo
& 0xFFF);
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;
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
);
10882 /* offset (kHz) = (dcLvl / 322) */
10883 carriers
->a
.shift
= (DRX_U16TODRXFREQ(dcLvlA
) / 322L);
10884 carriers
->b
.shift
= (DRX_U16TODRXFREQ(dcLvlB
) / 322L);
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
);
10890 carriers
->a
.thres
= cmThesA
;
10891 carriers
->b
.thres
= cmThesB
;
10895 return DRX_STS_ERROR
;
10898 /*============================================================================*/
10900 * \brief Set Audio Carrier settings
10901 * \param demod instance of demodulator
10902 * \param pointer to pDRXAudCarrier_t
10903 * \return DRXStatus_t.
10907 AUDCtrlSetCfgCarrier(pDRXDemodInstance_t demod
, pDRXCfgAudCarriers_t carriers
)
10909 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
10910 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
10923 if (carriers
== NULL
) {
10924 return DRX_STS_INVALID_ARG
;
10927 devAddr
= demod
->myI2CDevAddr
;
10928 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
10931 if (extAttr
->audData
.audioIsActive
== FALSE
) {
10932 CHK_ERROR(PowerUpAud(demod
, TRUE
));
10933 extAttr
->audData
.audioIsActive
= TRUE
;
10936 CHK_ERROR(AUDGetModus(demod
, &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
;
10945 case DRX_NO_CARRIER_NOISE
:
10946 wModus
|= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE
;
10949 return DRX_STS_INVALID_ARG
;
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
;
10959 case DRX_NO_CARRIER_NOISE
:
10960 wModus
|= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE
;
10963 return DRX_STS_INVALID_ARG
;
10967 /* now update the modus register */
10968 if (wModus
!= rModus
) {
10969 WR16(devAddr
, AUD_DEM_WR_MODUS__A
, wModus
);
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);
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);
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
);
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
);
10990 /* update DRXK data structure */
10991 extAttr
->audData
.carriers
= *carriers
;
10995 return DRX_STS_ERROR
;
10998 /*============================================================================*/
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.
11007 AUDCtrlGetCfgMixer(pDRXDemodInstance_t demod
, pDRXCfgAudMixer_t mixer
)
11009 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11010 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11012 u16_t srcI2SMatr
= 0;
11015 if (mixer
== NULL
) {
11016 return DRX_STS_INVALID_ARG
;
11019 devAddr
= demod
->myI2CDevAddr
;
11020 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11023 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11024 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11025 extAttr
->audData
.audioIsActive
= TRUE
;
11028 /* Source Selctor */
11029 RR16(devAddr
, AUD_DSP_WR_SRC_I2S_MATR__A
, &srcI2SMatr
);
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
;
11035 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB
:
11036 mixer
->sourceI2S
= DRX_AUD_SRC_STEREO_OR_AB
;
11038 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A
:
11039 mixer
->sourceI2S
= DRX_AUD_SRC_STEREO_OR_A
;
11041 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B
:
11042 mixer
->sourceI2S
= DRX_AUD_SRC_STEREO_OR_B
;
11045 return DRX_STS_ERROR
;
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
;
11053 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO
:
11054 mixer
->matrixI2S
= DRX_AUD_I2S_MATRIX_STEREO
;
11056 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A
:
11057 mixer
->matrixI2S
= DRX_AUD_I2S_MATRIX_A_MONO
;
11059 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B
:
11060 mixer
->matrixI2S
= DRX_AUD_I2S_MATRIX_B_MONO
;
11063 return DRX_STS_ERROR
;
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
;
11072 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX
:
11073 mixer
->matrixFm
= DRX_AUD_FM_MATRIX_GERMAN
;
11075 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX
:
11076 mixer
->matrixFm
= DRX_AUD_FM_MATRIX_KOREAN
;
11078 case AUD_DEM_WR_FM_MATRIX_SOUND_A
:
11079 mixer
->matrixFm
= DRX_AUD_FM_MATRIX_SOUND_A
;
11081 case AUD_DEM_WR_FM_MATRIX_SOUND_B
:
11082 mixer
->matrixFm
= DRX_AUD_FM_MATRIX_SOUND_B
;
11085 return DRX_STS_ERROR
;
11090 return DRX_STS_ERROR
;
11093 /*============================================================================*/
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.
11102 AUDCtrlSetCfgMixer(pDRXDemodInstance_t demod
, pDRXCfgAudMixer_t mixer
)
11104 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11105 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11107 u16_t srcI2SMatr
= 0;
11110 if (mixer
== NULL
) {
11111 return DRX_STS_INVALID_ARG
;
11114 devAddr
= demod
->myI2CDevAddr
;
11115 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11118 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11119 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11120 extAttr
->audData
.audioIsActive
= TRUE
;
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
;
11127 switch (mixer
->sourceI2S
) {
11128 case DRX_AUD_SRC_MONO
:
11129 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO
;
11131 case DRX_AUD_SRC_STEREO_OR_AB
:
11132 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB
;
11134 case DRX_AUD_SRC_STEREO_OR_A
:
11135 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A
;
11137 case DRX_AUD_SRC_STEREO_OR_B
:
11138 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B
;
11141 return DRX_STS_INVALID_ARG
;
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
;
11150 case DRX_AUD_I2S_MATRIX_STEREO
:
11151 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO
;
11153 case DRX_AUD_I2S_MATRIX_A_MONO
:
11154 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A
;
11156 case DRX_AUD_I2S_MATRIX_B_MONO
:
11157 srcI2SMatr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B
;
11160 return DRX_STS_INVALID_ARG
;
11162 /* write the result */
11163 WR16(devAddr
, AUD_DSP_WR_SRC_I2S_MATR__A
, srcI2SMatr
);
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
;
11172 case DRX_AUD_FM_MATRIX_GERMAN
:
11173 fmMatr
|= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX
;
11175 case DRX_AUD_FM_MATRIX_KOREAN
:
11176 fmMatr
|= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX
;
11178 case DRX_AUD_FM_MATRIX_SOUND_A
:
11179 fmMatr
|= AUD_DEM_WR_FM_MATRIX_SOUND_A
;
11181 case DRX_AUD_FM_MATRIX_SOUND_B
:
11182 fmMatr
|= AUD_DEM_WR_FM_MATRIX_SOUND_B
;
11185 return DRX_STS_INVALID_ARG
;
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
);
11193 /* update the data structure with hardware state */
11194 extAttr
->audData
.mixer
= *mixer
;
11198 return DRX_STS_ERROR
;
11201 /*============================================================================*/
11203 * \brief Set AV Sync settings
11204 * \param demod instance of demodulator
11205 * \param pointer to DRXICfgAVSync_t
11206 * \return DRXStatus_t.
11210 AUDCtrlSetCfgAVSync(pDRXDemodInstance_t demod
, pDRXCfgAudAVSync_t avSync
)
11212 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11213 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11215 u16_t wAudVidSync
= 0;
11217 if (avSync
== NULL
) {
11218 return DRX_STS_INVALID_ARG
;
11221 devAddr
= demod
->myI2CDevAddr
;
11222 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11225 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11226 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11227 extAttr
->audData
.audioIsActive
= TRUE
;
11230 /* audio/video synchronisation */
11231 RR16(devAddr
, AUD_DSP_WR_AV_SYNC__A
, &wAudVidSync
);
11233 wAudVidSync
&= (u16_t
) ~ AUD_DSP_WR_AV_SYNC_AV_ON__M
;
11235 if (*avSync
== DRX_AUD_AVSYNC_OFF
) {
11236 wAudVidSync
|= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE
;
11238 wAudVidSync
|= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE
;
11241 wAudVidSync
&= (u16_t
) ~ AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M
;
11244 case DRX_AUD_AVSYNC_NTSC
:
11245 wAudVidSync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC
;
11247 case DRX_AUD_AVSYNC_MONOCHROME
:
11248 wAudVidSync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME
;
11250 case DRX_AUD_AVSYNC_PAL_SECAM
:
11251 wAudVidSync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM
;
11253 case DRX_AUD_AVSYNC_OFF
:
11257 return DRX_STS_INVALID_ARG
;
11260 WR16(devAddr
, AUD_DSP_WR_AV_SYNC__A
, wAudVidSync
);
11263 return DRX_STS_ERROR
;
11266 /*============================================================================*/
11268 * \brief Get AV Sync settings
11269 * \param demod instance of demodulator
11270 * \param pointer to DRXICfgAVSync_t
11271 * \return DRXStatus_t.
11275 AUDCtrlGetCfgAVSync(pDRXDemodInstance_t demod
, pDRXCfgAudAVSync_t avSync
)
11277 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11278 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11280 u16_t wAudVidSync
= 0;
11282 if (avSync
== NULL
) {
11283 return DRX_STS_INVALID_ARG
;
11286 devAddr
= demod
->myI2CDevAddr
;
11287 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11290 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11291 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11292 extAttr
->audData
.audioIsActive
= TRUE
;
11295 /* audio/video synchronisation */
11296 RR16(devAddr
, AUD_DSP_WR_AV_SYNC__A
, &wAudVidSync
);
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
;
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
;
11308 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME
:
11309 *avSync
= DRX_AUD_AVSYNC_MONOCHROME
;
11311 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM
:
11312 *avSync
= DRX_AUD_AVSYNC_PAL_SECAM
;
11315 return DRX_STS_ERROR
;
11320 return DRX_STS_ERROR
;
11323 /*============================================================================*/
11325 * \brief Get deviation mode
11326 * \param demod instance of demodulator
11327 * \param pointer to DRXCfgAudDeviation_t
11328 * \return DRXStatus_t.
11332 AUDCtrlGetCfgDev(pDRXDemodInstance_t demod
, pDRXCfgAudDeviation_t dev
)
11334 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11335 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11340 return DRX_STS_INVALID_ARG
;
11343 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11344 devAddr
= demod
->myI2CDevAddr
;
11346 CHK_ERROR(AUDGetModus(demod
, &rModus
));
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
;
11352 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION
:
11353 *dev
= DRX_AUD_DEVIATION_HIGH
;
11356 return DRX_STS_ERROR
;
11361 return DRX_STS_ERROR
;
11364 /*============================================================================*/
11366 * \brief Get deviation mode
11367 * \param demod instance of demodulator
11368 * \param pointer to DRXCfgAudDeviation_t
11369 * \return DRXStatus_t.
11373 AUDCtrlSetCfgDev(pDRXDemodInstance_t demod
, pDRXCfgAudDeviation_t dev
)
11375 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11376 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11382 return DRX_STS_INVALID_ARG
;
11385 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11386 devAddr
= demod
->myI2CDevAddr
;
11388 CHK_ERROR(AUDGetModus(demod
, &rModus
));
11392 wModus
&= (u16_t
) ~ AUD_DEM_WR_MODUS_MOD_HDEV_A__M
;
11395 case DRX_AUD_DEVIATION_NORMAL
:
11396 wModus
|= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL
;
11398 case DRX_AUD_DEVIATION_HIGH
:
11399 wModus
|= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION
;
11402 return DRX_STS_INVALID_ARG
;
11405 /* now update the modus register */
11406 if (wModus
!= rModus
) {
11407 WR16(devAddr
, AUD_DEM_WR_MODUS__A
, wModus
);
11409 /* store in drxk data struct */
11410 extAttr
->audData
.deviation
= *dev
;
11414 return DRX_STS_ERROR
;
11417 /*============================================================================*/
11419 * \brief Get Prescaler settings
11420 * \param demod instance of demodulator
11421 * \param pointer to DRXCfgAudPrescale_t
11422 * \return DRXStatus_t.
11426 AUDCtrlGetCfgPrescale(pDRXDemodInstance_t demod
, pDRXCfgAudPrescale_t presc
)
11428 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11429 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11431 u16_t rMaxFMDeviation
= 0;
11432 u16_t rNicamPrescaler
= 0;
11434 if (presc
== NULL
) {
11435 return DRX_STS_INVALID_ARG
;
11438 devAddr
= demod
->myI2CDevAddr
;
11439 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11442 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11443 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11444 extAttr
->audData
.audioIsActive
= TRUE
;
11447 /* read register data */
11448 RR16(devAddr
, AUD_DSP_WR_NICAM_PRESC__A
, &rNicamPrescaler
);
11449 RR16(devAddr
, AUD_DSP_WR_FM_PRESC__A
, &rMaxFMDeviation
);
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
;
11457 presc
->fmDeviation
= 380; /* kHz */
11460 /* calculate NICAM gain from pre-scaler */
11462 nicamGain = 20 * ( log10( preScaler / 16) )
11463 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
11465 because Log10Times100() cannot return negative numbers
11466 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
11468 for 0.1dB resolution:
11470 nicamGain = 200 * ( log10( preScaler / 16) )
11471 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
11472 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
11475 rNicamPrescaler
>>= 8;
11476 if (rNicamPrescaler
<= 1) {
11477 presc
->nicamGain
= -241;
11480 presc
->nicamGain
= (s16_t
) (((s32_t
)
11482 (10 * rNicamPrescaler
*
11483 rNicamPrescaler
)) - (s32_t
)
11484 (Log10Times100(10 * 16 * 16))));
11489 return DRX_STS_ERROR
;
11492 /*============================================================================*/
11494 * \brief Set Prescaler settings
11495 * \param demod instance of demodulator
11496 * \param pointer to DRXCfgAudPrescale_t
11497 * \return DRXStatus_t.
11501 AUDCtrlSetCfgPrescale(pDRXDemodInstance_t demod
, pDRXCfgAudPrescale_t presc
)
11503 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11504 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11506 u16_t wMaxFMDeviation
= 0;
11507 u16_t nicamPrescaler
;
11509 if (presc
== NULL
) {
11510 return DRX_STS_INVALID_ARG
;
11513 devAddr
= demod
->myI2CDevAddr
;
11514 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11517 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11518 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11519 extAttr
->audData
.audioIsActive
= TRUE
;
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
) {
11528 AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION
;
11531 /* NICAM Prescaler */
11532 if ((presc
->nicamGain
>= -241) && (presc
->nicamGain
<= 180)) {
11535 prescaler = 16 * 10^( GdB / 20 )
11537 minval of GdB = -20*log( 16 ) = -24.1dB
11539 negative numbers not allowed for dB2LinTimes100, so
11541 prescaler = 16 * 10^( GdB / 20 )
11542 = 10^( (GdB / 20) + log10(16) )
11543 = 10^( (GdB + 20log10(16)) / 20 )
11547 = 10^( G0.1dB + 200log10(16)) / 200 )
11550 nicamPrescaler
= (u16_t
)
11551 ((dB2LinTimes100(presc
->nicamGain
+ 241UL) + 50UL) / 100UL);
11554 if (nicamPrescaler
> 127) {
11555 nicamPrescaler
= 127;
11558 /* shift before writing to register */
11559 nicamPrescaler
<<= 8;
11561 return (DRX_STS_INVALID_ARG
);
11563 /* end of setting NICAM Prescaler */
11565 WR16(devAddr
, AUD_DSP_WR_NICAM_PRESC__A
, nicamPrescaler
);
11566 WR16(devAddr
, AUD_DSP_WR_FM_PRESC__A
, wMaxFMDeviation
);
11568 extAttr
->audData
.prescale
= *presc
;
11572 return DRX_STS_ERROR
;
11575 /*============================================================================*/
11578 * \param demod instance of demodulator
11579 * \param pointer to DRXAudBeep_t
11580 * \return DRXStatus_t.
11583 static DRXStatus_t
AUDCtrlBeep(pDRXDemodInstance_t demod
, pDRXAudBeep_t beep
)
11585 pI2CDeviceAddr_t devAddr
= (pI2CDeviceAddr_t
) NULL
;
11586 pDRXJData_t extAttr
= (pDRXJData_t
) NULL
;
11590 u32_t frequency
= 0;
11592 if (beep
== NULL
) {
11593 return DRX_STS_INVALID_ARG
;
11596 devAddr
= demod
->myI2CDevAddr
;
11597 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11600 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11601 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11602 extAttr
->audData
.audioIsActive
= TRUE
;
11605 if ((beep
->volume
> 0) || (beep
->volume
< -127)) {
11606 return DRX_STS_INVALID_ARG
;
11609 if (beep
->frequency
> 3000) {
11610 return DRX_STS_INVALID_ARG
;
11613 volume
= (u16_t
) beep
->volume
+ 127;
11614 theBeep
|= volume
<< AUD_DSP_WR_BEEPER_BEEP_VOLUME__B
;
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
;
11620 theBeep
|= (u16_t
) frequency
;
11622 if (beep
->mute
== TRUE
) {
11626 WR16(devAddr
, AUD_DSP_WR_BEEPER__A
, theBeep
);
11630 return DRX_STS_ERROR
;
11633 /*============================================================================*/
11635 * \brief Set an audio standard
11636 * \param demod instance of demodulator
11637 * \param pointer to DRXAudStandard_t
11638 * \return DRXStatus_t.
11642 AUDCtrlSetStandard(pDRXDemodInstance_t demod
, pDRXAudStandard_t standard
)
11644 pI2CDeviceAddr_t devAddr
= NULL
;
11645 pDRXJData_t extAttr
= NULL
;
11646 DRXStandard_t currentStandard
= DRX_STANDARD_UNKNOWN
;
11648 u16_t wStandard
= 0;
11652 Bool_t muteBuffer
= FALSE
;
11653 s16_t volumeBuffer
= 0;
11656 if (standard
== NULL
) {
11657 return DRX_STS_INVALID_ARG
;
11660 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
11661 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11664 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11665 CHK_ERROR(PowerUpAud(demod
, FALSE
));
11666 extAttr
->audData
.audioIsActive
= TRUE
;
11669 /* reset RDS data availability flag */
11670 extAttr
->audData
.rdsDataPresent
= FALSE
;
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
;
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
));
11687 /* get prescaler from presets */
11688 CHK_ERROR(AUDCtrlSetCfgPrescale(demod
, &extAttr
->audData
.prescale
));
11690 CHK_ERROR(AUDGetModus(demod
, &rModus
));
11694 switch (*standard
) {
11695 case DRX_AUD_STANDARD_AUTO
:
11696 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO
;
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
;
11704 case DRX_AUD_STANDARD_A2
:
11705 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA
;
11707 case DRX_AUD_STANDARD_EIAJ
:
11708 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J
;
11710 case DRX_AUD_STANDARD_FM_STEREO
:
11711 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO
;
11713 case DRX_AUD_STANDARD_BG_FM
:
11714 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM
;
11716 case DRX_AUD_STANDARD_D_K1
:
11717 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1
;
11719 case DRX_AUD_STANDARD_D_K2
:
11720 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2
;
11722 case DRX_AUD_STANDARD_D_K3
:
11723 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3
;
11725 case DRX_AUD_STANDARD_BG_NICAM_FM
:
11726 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM
;
11728 case DRX_AUD_STANDARD_L_NICAM_AM
:
11729 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM
;
11731 case DRX_AUD_STANDARD_I_NICAM_FM
:
11732 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM
;
11734 case DRX_AUD_STANDARD_D_K_NICAM_FM
:
11735 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM
;
11737 case DRX_AUD_STANDARD_UNKNOWN
:
11738 wStandard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO
;
11741 return DRX_STS_ERROR
;
11744 if (*standard
== DRX_AUD_STANDARD_AUTO
) {
11745 /* we need the current standard here */
11746 currentStandard
= extAttr
->standard
;
11748 wModus
&= (u16_t
) ~ AUD_DEM_WR_MODUS_MOD_6_5MHZ__M
;
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
);
11754 wModus
|= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K
);
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
);
11761 } else { /* non USA, ignore standard M to save time */
11763 wModus
|= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA
);
11768 wModus
&= (u16_t
) ~ AUD_DEM_WR_MODUS_MOD_FMRADIO__M
;
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
);
11774 wModus
|= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U
);
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 */
11782 wModus
|= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP
);
11785 if (wModus
!= rModus
) {
11786 WR16(devAddr
, AUD_DEM_WR_MODUS__A
, wModus
);
11789 WR16(devAddr
, AUD_DEM_WR_STANDARD_SEL__A
, wStandard
);
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
);
11803 /* write standard selected */
11804 extAttr
->audData
.audioStandard
= *standard
;
11808 return DRX_STS_ERROR
;
11811 /*============================================================================*/
11813 * \brief Get the current audio standard
11814 * \param demod instance of demodulator
11815 * \param pointer to DRXAudStandard_t
11816 * \return DRXStatus_t.
11820 AUDCtrlGetStandard(pDRXDemodInstance_t demod
, pDRXAudStandard_t standard
)
11822 pI2CDeviceAddr_t devAddr
= NULL
;
11823 pDRXJData_t extAttr
= NULL
;
11827 if (standard
== NULL
) {
11828 return DRX_STS_INVALID_ARG
;
11831 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
11832 devAddr
= (pI2CDeviceAddr_t
) demod
->myI2CDevAddr
;
11835 if (extAttr
->audData
.audioIsActive
== FALSE
) {
11836 CHK_ERROR(PowerUpAud(demod
, TRUE
));
11837 extAttr
->audData
.audioIsActive
= TRUE
;
11840 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
11842 RR16(devAddr
, AUD_DEM_RD_STANDARD_RES__A
, &rData
);
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
;
11850 /* detection done, return correct standard */
11852 /* no standard detected */
11853 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD
:
11854 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
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
;
11860 /* standard is EIA-J (Japan) */
11861 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J
:
11862 *standard
= DRX_AUD_STANDARD_EIAJ
;
11864 /* standard is BTSC-stereo */
11865 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO
:
11866 *standard
= DRX_AUD_STANDARD_BTSC
;
11868 /* standard is BTSC-mono (SAP) */
11869 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP
:
11870 *standard
= DRX_AUD_STANDARD_BTSC
;
11872 /* standard is FM radio */
11873 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO
:
11874 *standard
= DRX_AUD_STANDARD_FM_STEREO
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
11909 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
11914 return DRX_STS_ERROR
;
11918 /*============================================================================*/
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.
11927 FmLockStatus(pDRXDemodInstance_t demod
, pDRXLockStatus_t lockStat
)
11929 DRXAudStatus_t status
;
11931 /* Check detection of audio carriers */
11932 CHK_ERROR(AUDCtrlGetCarrierDetectStatus(demod
, &status
));
11934 /* locked if either primary or secondary carrier is detected */
11935 if ((status
.carrierA
== TRUE
) || (status
.carrierB
== TRUE
)) {
11936 *lockStat
= DRX_LOCKED
;
11938 *lockStat
= DRX_NOT_LOCKED
;
11941 return (DRX_STS_OK
);
11944 return (DRX_STS_ERROR
);
11947 /*============================================================================*/
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.
11954 * Only the quality indicator field is will be supplied.
11955 * This will either be 0% or 100%, nothing in between.
11959 FmSigQuality(pDRXDemodInstance_t demod
, pDRXSigQuality_t sigQuality
)
11961 DRXLockStatus_t lockStatus
= DRX_NOT_LOCKED
;
11963 CHK_ERROR(FmLockStatus(demod
, &lockStatus
));
11964 if (lockStatus
== DRX_LOCKED
) {
11965 sigQuality
->indicator
= 100;
11967 sigQuality
->indicator
= 0;
11970 return (DRX_STS_OK
);
11973 return (DRX_STS_ERROR
);
11978 /*===========================================================================*/
11979 /*== END AUDIO DATAPATH FUNCTIONS ==*/
11980 /*===========================================================================*/
11982 /*============================================================================*/
11983 /*============================================================================*/
11984 /*== OOB DATAPATH FUNCTIONS ==*/
11985 /*============================================================================*/
11986 /*============================================================================*/
11987 #ifndef DRXJ_DIGITAL_ONLY
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.
11995 * Gets OOB lock status
11999 GetOOBLockStatus(pDRXDemodInstance_t demod
,
12000 pI2CDeviceAddr_t devAddr
, pDRXLockStatus_t oobLock
)
12002 DRXJSCUCmd_t scuCmd
;
12003 u16_t cmdResult
[2];
12004 u16_t OOBLockState
;
12006 *oobLock
= DRX_NOT_LOCKED
;
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;
12014 CHK_ERROR(SCUCommand(devAddr
, &scuCmd
));
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;
12026 if (OOBLockState
& 0x0008) {
12027 *oobLock
= DRXJ_OOB_SYNC_LOCK
;
12028 } else if ((OOBLockState
& 0x0002) && (OOBLockState
& 0x0001)) {
12029 *oobLock
= DRXJ_OOB_AGC_LOCK
;
12032 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
12033 *oobLock
= DRX_NEVER_LOCK
;
12036 /* *oobLock = scuCmd.result[1]; */
12038 return (DRX_STS_OK
);
12040 return (DRX_STS_ERROR
);
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.
12050 * Gets OOB frequency offset
12054 GetOOBSymbolRateOffset(pI2CDeviceAddr_t devAddr
, ps32_t SymbolRateOffset
)
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;
12071 u32_t symbolRate
= 0;
12072 Bool_t negative
= FALSE
;
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 */
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 */
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 */
12093 return (DRX_STS_ERROR
);
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;
12102 unsignedTimingOffset
= 0x00007FFF & (u32_t
) (-data
);
12105 unsignedTimingOffset
= (u32_t
) data
;
12107 symbolRate
= symbolRate
>> 5;
12108 unsignedTimingOffset
= (unsignedTimingOffset
* symbolRate
);
12109 unsignedTimingOffset
= Frac(unsignedTimingOffset
, 256, FRAC_ROUND
);
12110 unsignedTimingOffset
= Frac(unsignedTimingOffset
,
12111 divisionFactor
, FRAC_ROUND
);
12113 timingOffset
= (s32_t
) unsignedTimingOffset
;
12115 timingOffset
= -(s32_t
) unsignedTimingOffset
;
12117 *SymbolRateOffset
= timingOffset
;
12119 return (DRX_STS_OK
);
12121 return (DRX_STS_ERROR
);
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.
12131 * Gets OOB frequency offset
12135 GetOOBFreqOffset(pDRXDemodInstance_t demod
, pDRXFrequency_t freqOffset
)
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
;
12151 /* check arguments */
12152 if ((demod
== NULL
) || (freqOffset
== NULL
)) {
12153 return DRX_STS_INVALID_ARG
;
12156 devAddr
= demod
->myI2CDevAddr
;
12157 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
12161 /* read sign (spectrum inversion) */
12162 RR16(devAddr
, ORX_FWP_IQM_FRQ_W__A
, &rot
);
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);
12172 Mult32(data
, (commonAttr
->sysClockFreq
* 1000) / 6, &data64Hi
,
12174 tempFreqOffset
= (((data64Lo
>> 21) & 0x7ff) | (data64Hi
<< 11));
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;
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;
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;
12196 return (DRX_STS_ERROR
);
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 */
12208 fineFreqOffset
*= data
; /* Hz */
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 */
12215 if ((rot
& 0x8000) == 0x8000)
12216 *freqOffset
= -(coarseFreqOffset
+ fineFreqOffset
);
12218 *freqOffset
= (coarseFreqOffset
+ fineFreqOffset
);
12220 return (DRX_STS_OK
);
12222 return (DRX_STS_ERROR
);
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.
12232 * Gets OOB frequency
12236 GetOOBFrequency(pDRXDemodInstance_t demod
, pDRXFrequency_t frequency
)
12239 DRXFrequency_t freqOffset
= 0;
12240 DRXFrequency_t freq
= 0;
12241 pI2CDeviceAddr_t devAddr
= NULL
;
12243 devAddr
= demod
->myI2CDevAddr
;
12245 *frequency
= 0; /* KHz */
12247 SARR16(devAddr
, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A
, &data
);
12249 freq
= (DRXFrequency_t
) ((DRXFrequency_t
) data
* 50 + 50000L);
12251 CHK_ERROR(GetOOBFreqOffset(demod
, &freqOffset
));
12253 *frequency
= freq
+ freqOffset
;
12255 return (DRX_STS_OK
);
12257 return (DRX_STS_ERROR
);
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.
12267 * Gets OOB MER. Table for MER is in Programming guide.
12270 static DRXStatus_t
GetOOBMER(pI2CDeviceAddr_t devAddr
, pu32_t mer
)
12276 RR16(devAddr
, ORX_EQU_MER_MER_R__A
, &data
);
12278 case 0: /* fall through */
12315 case 13: /* fall through */
12319 case 15: /* fall through */
12323 case 17: /* fall through */
12327 case 19: /* fall through */
12331 case 21: /* fall through */
12335 case 23: /* fall through */
12336 case 24: /* fall through */
12340 case 26: /* fall through */
12341 case 27: /* fall through */
12345 case 29: /* fall through */
12346 case 30: /* fall through */
12347 case 31: /* fall through */
12351 case 33: /* fall through */
12352 case 34: /* fall through */
12353 case 35: /* fall through */
12357 case 37: /* fall through */
12358 case 38: /* fall through */
12359 case 39: /* fall through */
12363 case 41: /* fall through */
12364 case 42: /* fall through */
12365 case 43: /* fall through */
12366 case 44: /* fall through */
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 */
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 */
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 */
12398 return (DRX_STS_OK
);
12400 return (DRX_STS_ERROR
);
12402 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
12405 * \fn DRXStatus_t SetOrxNsuAox()
12406 * \brief Configure OrxNsuAox for OOB
12407 * \param demod instance of demodulator.
12409 * \return DRXStatus_t.
12411 static DRXStatus_t
SetOrxNsuAox(pDRXDemodInstance_t demod
, Bool_t active
)
12414 pI2CDeviceAddr_t devAddr
= NULL
;
12415 pDRXJData_t extAttr
= NULL
;
12417 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12418 devAddr
= demod
->myI2CDevAddr
;
12420 /* Configure NSU_AOX */
12421 RR16(devAddr
, ORX_NSU_AOX_STDBY_W__A
, &data
);
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
)
12432 } else { /* active */
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
);
12443 WR16(devAddr
, ORX_NSU_AOX_STDBY_W__A
, data
);
12445 return (DRX_STS_OK
);
12447 return (DRX_STS_ERROR
);
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.
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
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) */
12471 /* Coefficients for the nyquist fitler (total: 27 taps) */
12472 #define NYQFILTERLEN 27
12474 static DRXStatus_t
CtrlSetOOB(pDRXDemodInstance_t demod
, pDRXOOB_t oobParam
)
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
;
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 */
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) */
12502 devAddr
= demod
->myI2CDevAddr
;
12503 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12504 mirrorFreqSpectOOB
= extAttr
->mirrorFreqSpectOOB
;
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
);
12518 extAttr
->oobPowerOn
= FALSE
;
12519 return (DRX_STS_OK
);
12522 standard
= oobParam
->standard
;
12524 freq
= oobParam
->frequency
;
12525 if ((freq
< 70000) || (freq
> 130000))
12526 return (DRX_STS_ERROR
);
12527 freq
= (freq
- 50000) / 50;
12531 u16_t remainder
= 0;
12532 pu16_t trkFiltercfg
= extAttr
->oobTrkFilterCfg
;
12534 index
= (u16_t
) ((freq
- 400) / 200);
12535 remainder
= (u16_t
) ((freq
- 400) % 200);
12537 trkFiltercfg
[index
] - (trkFiltercfg
[index
] -
12538 trkFiltercfg
[index
+
12539 1]) / 10 * remainder
/
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
));
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
));
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
:
12573 /* signal is transmitted inverted */
12574 ((oobParam
->spectrumInverted
== TRUE
) &
12575 /* and tuner is not mirroring the signal */
12576 (mirrorFreqSpectOOB
== FALSE
)) |
12578 /* signal is transmitted noninverted */
12579 ((oobParam
->spectrumInverted
== FALSE
) &
12580 /* and tuner is mirroring the signal */
12581 (mirrorFreqSpectOOB
== TRUE
))
12583 setParamParameters
[0] =
12584 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC
;
12586 setParamParameters
[0] =
12587 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC
;
12589 case DRX_OOB_MODE_B_GRADE_A
:
12591 /* signal is transmitted inverted */
12592 ((oobParam
->spectrumInverted
== TRUE
) &
12593 /* and tuner is not mirroring the signal */
12594 (mirrorFreqSpectOOB
== FALSE
)) |
12596 /* signal is transmitted noninverted */
12597 ((oobParam
->spectrumInverted
== FALSE
) &
12598 /* and tuner is mirroring the signal */
12599 (mirrorFreqSpectOOB
== TRUE
))
12601 setParamParameters
[0] =
12602 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC
;
12604 setParamParameters
[0] =
12605 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC
;
12607 case DRX_OOB_MODE_B_GRADE_B
:
12610 /* signal is transmitted inverted */
12611 ((oobParam
->spectrumInverted
== TRUE
) &
12612 /* and tuner is not mirroring the signal */
12613 (mirrorFreqSpectOOB
== FALSE
)) |
12615 /* signal is transmitted noninverted */
12616 ((oobParam
->spectrumInverted
== FALSE
) &
12617 /* and tuner is mirroring the signal */
12618 (mirrorFreqSpectOOB
== TRUE
))
12620 setParamParameters
[0] =
12621 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC
;
12623 setParamParameters
[0] =
12624 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC
;
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
));
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 */
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);
12649 WR16(devAddr
, ORX_DDC_OFO_SET_W__A
, ORX_DDC_OFO_SET_W__PRE
);
12652 WR16(devAddr
, ORX_NSU_AOX_LOPOW_W__A
, extAttr
->oobLoPow
);
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
);
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);
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);
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);
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);
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);
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);
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);
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
);
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
]);
12719 WR16(devAddr
, ORX_FWP_NYQ_ADR_W__A
, 31);
12720 WR16(devAddr
, ORX_COMM_EXEC__A
, ORX_COMM_EXEC_ACTIVE
);
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
));
12731 CHK_ERROR(SetOrxNsuAox(demod
, TRUE
));
12732 WR16(devAddr
, ORX_NSU_AOX_STHR_W__A
, extAttr
->oobPreSaw
);
12734 extAttr
->oobPowerOn
= TRUE
;
12736 return (DRX_STS_OK
);
12739 return (DRX_STS_ERROR
);
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.
12750 CtrlGetOOB(pDRXDemodInstance_t demod
, pDRXOOBStatus_t oobStatus
)
12752 #ifndef DRXJ_DIGITAL_ONLY
12753 pI2CDeviceAddr_t devAddr
= NULL
;
12754 pDRXJData_t extAttr
= NULL
;
12757 devAddr
= demod
->myI2CDevAddr
;
12758 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12760 /* check arguments */
12761 if (oobStatus
== NULL
) {
12762 return (DRX_STS_INVALID_ARG
);
12765 if (extAttr
->oobPowerOn
== FALSE
)
12766 return (DRX_STS_ERROR
);
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
);
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
));
12780 return (DRX_STS_OK
);
12783 return (DRX_STS_ERROR
);
12787 * \fn DRXStatus_t CtrlSetCfgOOBPreSAW()
12788 * \brief Configure PreSAW treshold value
12789 * \param cfgData Pointer to configuration parameter
12790 * \return Error code
12792 #ifndef DRXJ_DIGITAL_ONLY
12794 CtrlSetCfgOOBPreSAW(pDRXDemodInstance_t demod
, pu16_t cfgData
)
12796 pI2CDeviceAddr_t devAddr
= NULL
;
12797 pDRXJData_t extAttr
= NULL
;
12799 if (cfgData
== NULL
) {
12800 return (DRX_STS_INVALID_ARG
);
12802 devAddr
= demod
->myI2CDevAddr
;
12803 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12805 WR16(devAddr
, ORX_NSU_AOX_STHR_W__A
, *cfgData
);
12806 extAttr
->oobPreSaw
= *cfgData
;
12807 return (DRX_STS_OK
);
12809 return (DRX_STS_ERROR
);
12814 * \fn DRXStatus_t CtrlGetCfgOOBPreSAW()
12815 * \brief Configure PreSAW treshold value
12816 * \param cfgData Pointer to configuration parameter
12817 * \return Error code
12819 #ifndef DRXJ_DIGITAL_ONLY
12821 CtrlGetCfgOOBPreSAW(pDRXDemodInstance_t demod
, pu16_t cfgData
)
12823 pDRXJData_t extAttr
= NULL
;
12825 if (cfgData
== NULL
) {
12826 return (DRX_STS_INVALID_ARG
);
12828 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12830 *cfgData
= extAttr
->oobPreSaw
;
12832 return (DRX_STS_OK
);
12837 * \fn DRXStatus_t CtrlSetCfgOOBLoPower()
12838 * \brief Configure LO Power value
12839 * \param cfgData Pointer to pDRXJCfgOobLoPower_t
12840 * \return Error code
12842 #ifndef DRXJ_DIGITAL_ONLY
12844 CtrlSetCfgOOBLoPower(pDRXDemodInstance_t demod
, pDRXJCfgOobLoPower_t cfgData
)
12846 pI2CDeviceAddr_t devAddr
= NULL
;
12847 pDRXJData_t extAttr
= NULL
;
12849 if (cfgData
== NULL
) {
12850 return (DRX_STS_INVALID_ARG
);
12852 devAddr
= demod
->myI2CDevAddr
;
12853 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12855 WR16(devAddr
, ORX_NSU_AOX_LOPOW_W__A
, *cfgData
);
12856 extAttr
->oobLoPow
= *cfgData
;
12857 return (DRX_STS_OK
);
12859 return (DRX_STS_ERROR
);
12864 * \fn DRXStatus_t CtrlGetCfgOOBLoPower()
12865 * \brief Configure LO Power value
12866 * \param cfgData Pointer to pDRXJCfgOobLoPower_t
12867 * \return Error code
12869 #ifndef DRXJ_DIGITAL_ONLY
12871 CtrlGetCfgOOBLoPower(pDRXDemodInstance_t demod
, pDRXJCfgOobLoPower_t cfgData
)
12873 pDRXJData_t extAttr
= NULL
;
12875 if (cfgData
== NULL
) {
12876 return (DRX_STS_INVALID_ARG
);
12878 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12880 *cfgData
= extAttr
->oobLoPow
;
12882 return (DRX_STS_OK
);
12885 /*============================================================================*/
12886 /*== END OOB DATAPATH FUNCTIONS ==*/
12887 /*============================================================================*/
12889 /*=============================================================================
12890 ===== MC command related functions ==========================================
12891 ===========================================================================*/
12893 /*=============================================================================
12894 ===== CtrlSetChannel() ==========================================================
12895 ===========================================================================*/
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.
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.
12908 CtrlSetChannel(pDRXDemodInstance_t demod
, pDRXChannel_t channel
)
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;
12927 /*== check arguments ======================================================*/
12928 if ((demod
== NULL
) || (channel
== NULL
)) {
12929 return DRX_STS_INVALID_ARG
;
12932 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
12933 devAddr
= demod
->myI2CDevAddr
;
12934 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
12935 standard
= extAttr
->standard
;
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 */
12955 case DRX_STANDARD_UNKNOWN
:
12957 return (DRX_STS_INVALID_ARG
);
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
;
12969 case DRX_BANDWIDTH_8MHZ
: /* fall through */
12970 case DRX_BANDWIDTH_7MHZ
: /* fall through */
12972 return (DRX_STS_INVALID_ARG
);
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
:
12982 case DRX_BANDWIDTH_6MHZ
: /* fall through */
12983 case DRX_BANDWIDTH_UNKNOWN
: /* fall through */
12985 return (DRX_STS_INVALID_ARG
);
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
;
12999 case DRX_BANDWIDTH_6MHZ
: /* fall through */
13000 case DRX_BANDWIDTH_7MHZ
: /* fall through */
13002 return (DRX_STS_INVALID_ARG
);
13007 /* For QAM annex A and annex C:
13008 -check symbolrate and constellation
13009 -derive bandwidth from symbolrate (input bandwidth is ignored)
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;
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
));
13023 if (channel
->symbolrate
< minSymbolRate
||
13024 channel
->symbolrate
> maxSymbolRate
) {
13025 return (DRX_STS_INVALID_ARG
);
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;
13037 if ((bandwidthTemp
% 100) >= 50) {
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
;
13051 return (DRX_STS_INVALID_ARG
);
13055 /* For QAM annex B:
13056 -check constellation
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
:
13065 return (DRX_STS_INVALID_ARG
);
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
:
13090 return (DRX_STS_INVALID_ARG
);
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
};
13098 switch (channel
->bandwidth
) {
13099 case DRX_BANDWIDTH_8MHZ
:
13102 case DRX_BANDWIDTH_7MHZ
:
13103 uio1
.value
= FALSE
;
13105 case DRX_BANDWIDTH_6MHZ
:
13106 uio1
.value
= FALSE
;
13108 case DRX_BANDWIDTH_UNKNOWN
:
13110 return (DRX_STS_INVALID_ARG
);
13113 CHK_ERROR(CtrlUIOWrite(demod
, &uio1
));
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
13130 tunerMode
|= TUNER_MODE_ANALOG
;
13131 tunerSetFreq
= channel
->frequency
;
13133 case DRX_STANDARD_FM
:
13134 /* center frequency (equals sound carrier) as input,
13135 tune to edge of SAW */
13136 tunerMode
|= TUNER_MODE_ANALOG
;
13138 channel
->frequency
+ DRXJ_FM_CARRIER_FREQ_OFFSET
;
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
:
13147 tunerMode
|= TUNER_MODE_DIGITAL
;
13148 tunerSetFreq
= channel
->frequency
;
13150 case DRX_STANDARD_UNKNOWN
:
13152 return (DRX_STS_ERROR
);
13153 } /* switch(standard) */
13155 tunerMode
|= TUNER_MODE_SWITCH
;
13156 switch (channel
->bandwidth
) {
13157 case DRX_BANDWIDTH_8MHZ
:
13158 tunerMode
|= TUNER_MODE_8MHZ
;
13160 case DRX_BANDWIDTH_7MHZ
:
13161 tunerMode
|= TUNER_MODE_7MHZ
;
13163 case DRX_BANDWIDTH_6MHZ
:
13164 tunerMode
|= TUNER_MODE_6MHZ
;
13167 /* TODO: for FM which bandwidth to use ?
13168 also check offset from centre frequency ?
13169 For now using 6MHz.
13171 tunerMode
|= TUNER_MODE_6MHZ
;
13173 /* return (DRX_STS_INVALID_ARG); */
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 */
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
));
13195 /* Get actual frequency set by tuner and compute offset */
13196 CHK_ERROR(DRXBSP_TUNER_GetFrequency(demod
->myTuner
,
13199 &intermediateFreq
));
13200 tunerFreqOffset
= tunerGetFreq
- tunerSetFreq
;
13201 commonAttr
->intermediateFreq
= intermediateFreq
;
13203 /* no tuner instance defined, use fixed intermediate frequency */
13204 tunerFreqOffset
= 0;
13205 intermediateFreq
= demod
->myCommonAttr
->intermediateFreq
;
13206 } /* if ( demod->myTuner != NULL ) */
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
;
13214 extAttr
->mirror
= channel
->mirror
;
13216 CHK_ERROR(SetVSB(demod
));
13217 CHK_ERROR(SetFrequency(demod
, channel
, tunerFreqOffset
));
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
;
13230 extAttr
->mirror
= channel
->mirror
;
13232 CHK_ERROR(SetATVChannel(demod
,
13233 tunerFreqOffset
, channel
, standard
));
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
));
13243 case DRX_STANDARD_UNKNOWN
:
13245 return (DRX_STS_ERROR
);
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
;
13254 if (commonAttr
->tunerPortNr
== 1) {
13255 /* close tuner bridge */
13256 bridgeClosed
= TRUE
;
13257 CHK_ERROR(CtrlI2CBridge(demod
, &bridgeClosed
));
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
));
13270 /* if ( demod->myTuner !=NULL ) */
13271 /* flag the packet error counter reset */
13272 extAttr
->resetPktErrAcc
= TRUE
;
13274 return (DRX_STS_OK
);
13276 return (DRX_STS_ERROR
);
13279 /*=============================================================================
13280 ===== CtrlGetChannel() ==========================================================
13281 ===========================================================================*/
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.
13290 CtrlGetChannel(pDRXDemodInstance_t demod
, pDRXChannel_t channel
)
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;
13306 /* check arguments */
13307 if ((demod
== NULL
) || (channel
== NULL
)) {
13308 return DRX_STS_INVALID_ARG
;
13311 devAddr
= demod
->myI2CDevAddr
;
13312 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13313 standard
= extAttr
->standard
;
13314 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
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
;
13333 if (demod
->myTuner
!= NULL
) {
13334 DRXFrequency_t tunerFreqOffset
= 0;
13335 Bool_t tunerMirror
= commonAttr
->mirrorFreqSpect
? FALSE
: TRUE
;
13337 /* Get frequency from tuner */
13338 CHK_ERROR(DRXBSP_TUNER_GetFrequency(demod
->myTuner
,
13340 &(channel
->frequency
),
13341 &intermediateFreq
));
13342 tunerFreqOffset
= channel
->frequency
- extAttr
->frequency
;
13343 if (tunerMirror
== TRUE
) {
13344 /* positive image */
13345 channel
->frequency
+= tunerFreqOffset
;
13347 /* negative image */
13348 channel
->frequency
-= tunerFreqOffset
;
13351 /* Handle sound carrier offset in RF domain */
13352 if (standard
== DRX_STANDARD_FM
) {
13353 channel
->frequency
-= DRXJ_FM_CARRIER_FREQ_OFFSET
;
13356 intermediateFreq
= commonAttr
->intermediateFreq
;
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;
13365 channel
->symbolrate
=
13366 Frac28(adcFrequency
, (iqmRcRateLo
+ (1 << 23))) >> 7;
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
;
13377 #ifndef DRXJ_VSB_ONLY
13378 case DRX_STANDARD_ITU_A
:
13379 case DRX_STANDARD_ITU_B
:
13380 case DRX_STANDARD_ITU_C
:
13382 /* get the channel frequency */
13383 CHK_ERROR(GetCTLFreqOffset
13384 (demod
, &CTLFreqOffset
));
13385 channel
->frequency
-= CTLFreqOffset
;
13387 if (standard
== DRX_STANDARD_ITU_B
) {
13388 channel
->bandwidth
= DRX_BANDWIDTH_6MHZ
;
13392 u32_t rollOff
= 113; /* default annex C */
13394 if (standard
== DRX_STANDARD_ITU_A
) {
13399 channel
->symbolrate
* rollOff
;
13400 bandwidth
= bandwidthTemp
/ 100;
13402 if ((bandwidthTemp
% 100) >= 50) {
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
;
13417 } /* if (standard == DRX_STANDARD_ITU_B) */
13420 DRXJSCUCmd_t cmdSCU
=
13422 /* parameterLen */ 0,
13424 /* parameter */ NULL
,
13427 u16_t cmdResult
[3] = { 0, 0, 0 };
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
));
13438 channel
->interleavemode
=
13439 (DRXInterleaveModes_t
) (cmdSCU
.
13443 switch (extAttr
->constellation
) {
13444 case DRX_CONSTELLATION_QAM256
:
13445 channel
->constellation
=
13446 DRX_CONSTELLATION_QAM256
;
13448 case DRX_CONSTELLATION_QAM128
:
13449 channel
->constellation
=
13450 DRX_CONSTELLATION_QAM128
;
13452 case DRX_CONSTELLATION_QAM64
:
13453 channel
->constellation
=
13454 DRX_CONSTELLATION_QAM64
;
13456 case DRX_CONSTELLATION_QAM32
:
13457 channel
->constellation
=
13458 DRX_CONSTELLATION_QAM32
;
13460 case DRX_CONSTELLATION_QAM16
:
13461 channel
->constellation
=
13462 DRX_CONSTELLATION_QAM16
;
13465 channel
->constellation
=
13466 DRX_CONSTELLATION_UNKNOWN
;
13467 return (DRX_STS_ERROR
);
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
));
13483 case DRX_STANDARD_UNKNOWN
: /* fall trough */
13485 return (DRX_STS_ERROR
);
13486 } /* switch ( standard ) */
13488 if (lockStatus
== DRX_LOCKED
) {
13489 channel
->mirror
= extAttr
->mirror
;
13492 /* if ( lockStatus == DRX_LOCKED ) */
13493 return (DRX_STS_OK
);
13495 return (DRX_STS_ERROR
);
13498 /*=============================================================================
13499 ===== SigQuality() ==========================================================
13500 ===========================================================================*/
13503 mer2indicator(u16_t mer
, u16_t minMer
, u16_t thresholdMer
, u16_t maxMer
)
13505 u16_t indicator
= 0;
13507 if (mer
< minMer
) {
13509 } else if (mer
< thresholdMer
) {
13510 if ((thresholdMer
- minMer
) != 0) {
13512 25 * (mer
- minMer
) / (thresholdMer
- minMer
);
13514 } else if (mer
< maxMer
) {
13515 if ((maxMer
- thresholdMer
) != 0) {
13517 25 + 75 * (mer
- thresholdMer
) / (maxMer
-
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.
13541 CtrlSigQuality(pDRXDemodInstance_t demod
, pDRXSigQuality_t sigQuality
)
13543 pI2CDeviceAddr_t devAddr
= NULL
;
13544 pDRXJData_t extAttr
= NULL
;
13545 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
13546 DRXLockStatus_t lockStatus
= DRX_NOT_LOCKED
;
13549 u16_t thresholdMer
= 0;
13551 /* Check arguments */
13552 if ((sigQuality
== NULL
) || (demod
== NULL
)) {
13553 return (DRX_STS_INVALID_ARG
);
13556 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13557 standard
= extAttr
->standard
;
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
));
13567 CHK_ERROR(GetVSBPostRSPckErr
13568 (devAddr
, &sigQuality
->packetError
));
13570 if (lockStatus
!= DRXJ_DEMOD_LOCK
&& lockStatus
!= DRX_LOCKED
) {
13571 sigQuality
->postViterbiBER
= 500000;
13572 sigQuality
->MER
= 20;
13573 sigQuality
->preViterbiBER
= 0;
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
));
13584 thresholdMer
= 145;
13585 sigQuality
->postReedSolomonBER
= 0;
13586 sigQuality
->scaleFactorBER
= 1000000;
13587 sigQuality
->indicator
=
13588 mer2indicator(sigQuality
->MER
, minMer
, thresholdMer
,
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;
13601 case DRX_CONSTELLATION_QAM128
:
13602 sigQuality
->MER
= 180;
13604 case DRX_CONSTELLATION_QAM64
:
13605 sigQuality
->MER
= 150;
13607 case DRX_CONSTELLATION_QAM32
:
13608 sigQuality
->MER
= 120;
13610 case DRX_CONSTELLATION_QAM16
:
13611 sigQuality
->MER
= 90;
13614 sigQuality
->MER
= 0;
13615 return (DRX_STS_ERROR
);
13619 switch (extAttr
->constellation
) {
13620 case DRX_CONSTELLATION_QAM256
:
13622 thresholdMer
= 270;
13625 case DRX_CONSTELLATION_QAM64
:
13627 thresholdMer
= 210;
13630 case DRX_CONSTELLATION_QAM128
:
13631 case DRX_CONSTELLATION_QAM32
:
13632 case DRX_CONSTELLATION_QAM16
:
13635 return (DRX_STS_ERROR
);
13637 sigQuality
->indicator
=
13638 mer2indicator(sigQuality
->MER
, minMer
, thresholdMer
,
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
));
13651 case DRX_STANDARD_FM
:
13652 CHK_ERROR(FmSigQuality(demod
, sigQuality
));
13656 return (DRX_STS_ERROR
);
13659 return (DRX_STS_OK
);
13661 return (DRX_STS_ERROR
);
13664 /*============================================================================*/
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.
13675 CtrlLockStatus(pDRXDemodInstance_t demod
, pDRXLockStatus_t lockStat
)
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,
13683 /* *parameter */ NULL
,
13686 u16_t cmdResult
[2] = { 0, 0 };
13687 u16_t demodLock
= SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED
;
13689 /* check arguments */
13690 if ((demod
== NULL
) || (lockStat
== NULL
)) {
13691 return (DRX_STS_INVALID_ARG
);
13694 devAddr
= demod
->myI2CDevAddr
;
13695 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13696 standard
= extAttr
->standard
;
13698 *lockStat
= DRX_NOT_LOCKED
;
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
;
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
;
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
;
13725 case DRX_STANDARD_FM
:
13726 return FmLockStatus(demod
, lockStat
);
13728 case DRX_STANDARD_UNKNOWN
: /* fallthrough */
13730 return (DRX_STS_ERROR
);
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
));
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
;
13751 /* 0xC000 NEVER LOCKED */
13752 /* (system will never be able to lock to the signal) */
13753 *lockStat
= DRX_NEVER_LOCK
;
13756 return (DRX_STS_OK
);
13758 return (DRX_STS_ERROR
);
13761 /*============================================================================*/
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.
13772 CtrlConstel(pDRXDemodInstance_t demod
, pDRXComplex_t complexNr
)
13774 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
13775 /**< active standard */
13777 /* check arguments */
13778 if ((demod
== NULL
) || (complexNr
== NULL
)) {
13779 return (DRX_STS_INVALID_ARG
);
13782 /* read device info */
13783 standard
= ((pDRXJData_t
) demod
->myExtAttr
)->standard
;
13785 /* Read constellation point */
13786 switch (standard
) {
13787 case DRX_STANDARD_8VSB
:
13788 CHK_ERROR(CtrlGetVSBConstel(demod
, complexNr
));
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
));
13797 case DRX_STANDARD_UNKNOWN
:
13799 return (DRX_STS_ERROR
);
13802 return (DRX_STS_OK
);
13804 return (DRX_STS_ERROR
);
13807 /*============================================================================*/
13810 * \fn DRXStatus_t CtrlSetStandard()
13811 * \brief Set modulation standard to be used.
13812 * \param standard Modulation standard.
13813 * \return DRXStatus_t.
13815 * Setup stuff for the desired demodulation standard.
13816 * Disable and power down the previous selected demodulation standard
13820 CtrlSetStandard(pDRXDemodInstance_t demod
, pDRXStandard_t standard
)
13822 pDRXJData_t extAttr
= NULL
;
13823 DRXStandard_t prevStandard
;
13825 /* check arguments */
13826 if ((standard
== NULL
) || (demod
== NULL
)) {
13827 return (DRX_STS_INVALID_ARG
);
13830 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13831 prevStandard
= extAttr
->standard
;
13834 Stop and power down previous standard
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
));
13844 case DRX_STANDARD_8VSB
:
13845 CHK_ERROR(PowerDownVSB(demod
, FALSE
));
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
));
13858 case DRX_STANDARD_UNKNOWN
:
13861 case DRX_STANDARD_AUTO
: /* fallthrough */
13863 return (DRX_STS_INVALID_ARG
);
13867 Initialize channel independent registers
13868 Power up new standard
13870 extAttr
->standard
= *standard
;
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
:
13880 case DRX_STANDARD_8VSB
:
13881 CHK_ERROR(SetVSBLeakNGain(demod
));
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
));
13896 extAttr
->standard
= DRX_STANDARD_UNKNOWN
;
13897 return (DRX_STS_INVALID_ARG
);
13901 return (DRX_STS_OK
);
13903 /* Don't know what the standard is now ... try again */
13904 extAttr
->standard
= DRX_STANDARD_UNKNOWN
;
13905 return (DRX_STS_ERROR
);
13908 /*============================================================================*/
13911 * \fn DRXStatus_t CtrlGetStandard()
13912 * \brief Get modulation standard currently used to demodulate.
13913 * \param standard Modulation standard.
13914 * \return DRXStatus_t.
13916 * Returns 8VSB, NTSC, QAM only.
13920 CtrlGetStandard(pDRXDemodInstance_t demod
, pDRXStandard_t standard
)
13922 pDRXJData_t extAttr
= NULL
;
13923 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13925 /* check arguments */
13926 if (standard
== NULL
) {
13927 return (DRX_STS_INVALID_ARG
);
13929 (*standard
) = extAttr
->standard
;
13932 return (DRX_STS_OK
);
13934 return (DRX_STS_ERROR
);
13937 /*============================================================================*/
13940 * \fn DRXStatus_t CtrlGetCfgSymbolClockOffset()
13941 * \brief Get frequency offsets of STR.
13942 * \param pointer to s32_t.
13943 * \return DRXStatus_t.
13947 CtrlGetCfgSymbolClockOffset(pDRXDemodInstance_t demod
, ps32_t rateOffset
)
13949 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
13950 pI2CDeviceAddr_t devAddr
= NULL
;
13951 pDRXJData_t extAttr
= NULL
;
13953 /* check arguments */
13954 if (rateOffset
== NULL
) {
13955 return (DRX_STS_INVALID_ARG
);
13958 devAddr
= demod
->myI2CDevAddr
;
13959 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
13960 standard
= extAttr
->standard
;
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
:
13969 CHK_ERROR(GetSTRFreqOffset(demod
, rateOffset
));
13971 case DRX_STANDARD_NTSC
:
13972 case DRX_STANDARD_UNKNOWN
:
13974 return (DRX_STS_INVALID_ARG
);
13977 return (DRX_STS_OK
);
13979 return (DRX_STS_ERROR
);
13982 /*============================================================================*/
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.
13997 CtrlPowerMode(pDRXDemodInstance_t demod
, pDRXPowerMode_t mode
)
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;
14004 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
14005 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14006 devAddr
= demod
->myI2CDevAddr
;
14008 /* Check arguments */
14009 if (mode
== NULL
) {
14010 return (DRX_STS_INVALID_ARG
);
14013 /* If already in requested power mode, do nothing */
14014 if (commonAttr
->currentPowerMode
== *mode
) {
14015 return (DRX_STS_OK
);
14020 case DRXJ_POWER_DOWN_MAIN_PATH
:
14021 sioCcPwdMode
= SIO_CC_PWD_MODE_LEVEL_NONE
;
14023 case DRXJ_POWER_DOWN_CORE
:
14024 sioCcPwdMode
= SIO_CC_PWD_MODE_LEVEL_CLOCK
;
14026 case DRXJ_POWER_DOWN_PLL
:
14027 sioCcPwdMode
= SIO_CC_PWD_MODE_LEVEL_PLL
;
14029 case DRX_POWER_DOWN
:
14030 sioCcPwdMode
= SIO_CC_PWD_MODE_LEVEL_OSC
;
14033 /* Unknow sleep mode */
14034 return (DRX_STS_INVALID_ARG
);
14038 /* Check if device needs to be powered up */
14039 if ((commonAttr
->currentPowerMode
!= DRX_POWER_UP
)) {
14040 CHK_ERROR(PowerUpDevice(demod
));
14043 if ((*mode
== DRX_POWER_UP
)) {
14044 /* Restore analog & pin configuartion */
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 */
14054 Stop and power down previous standard
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
));
14063 case DRX_STANDARD_8VSB
:
14064 CHK_ERROR(PowerDownVSB(demod
, TRUE
));
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
));
14075 case DRX_STANDARD_UNKNOWN
:
14078 case DRX_STANDARD_AUTO
: /* fallthrough */
14080 return (DRX_STS_ERROR
);
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
);
14087 /* Initialize HI, wakeup key especially before put IC to sleep */
14088 CHK_ERROR(InitHI(demod
));
14090 extAttr
->HICfgCtrl
|= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ
;
14091 CHK_ERROR(HICfgCommand(demod
));
14095 commonAttr
->currentPowerMode
= *mode
;
14097 return (DRX_STS_OK
);
14099 return (DRX_STS_ERROR
);
14102 /*============================================================================*/
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.
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.
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
14120 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
14121 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
14125 CtrlVersion(pDRXDemodInstance_t demod
, pDRXVersionList_t
* versionList
)
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 */
14142 static char ucodeName
[] = "Microcode";
14143 static char deviceName
[] = "Device";
14145 devAddr
= demod
->myI2CDevAddr
;
14146 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14147 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
14149 /* Microcode version *************************************** */
14151 extAttr
->vVersion
[0].moduleType
= DRX_MODULE_MICROCODE
;
14152 extAttr
->vVersion
[0].moduleName
= ucodeName
;
14153 extAttr
->vVersion
[0].vString
= extAttr
->vText
[0];
14155 if (commonAttr
->isOpened
== TRUE
) {
14156 SARR16(devAddr
, SCU_RAM_VERSION_HI__A
, &ucodeMajorMinor
);
14157 SARR16(devAddr
, SCU_RAM_VERSION_LO__A
, &ucodePatch
);
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);
14168 patch
+= (10 * (ucodePatch
& 0xF));
14170 patch
+= (100 * (ucodePatch
& 0xF));
14172 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
14177 extAttr
->vVersion
[0].vMajor
= major
;
14178 extAttr
->vVersion
[0].vMinor
= minor
;
14179 extAttr
->vVersion
[0].vPatch
= patch
;
14181 if (major
/ 10 != 0) {
14182 extAttr
->vVersion
[0].vString
[idx
++] =
14183 ((char)(major
/ 10)) + '0';
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';
14195 if (patch
/ 10 != 0) {
14196 extAttr
->vVersion
[0].vString
[idx
++] =
14197 ((char)(patch
/ 10)) + '0';
14200 extAttr
->vVersion
[0].vString
[idx
++] = ((char)patch
) + '0';
14201 extAttr
->vVersion
[0].vString
[idx
] = '\0';
14203 extAttr
->vListElements
[0].version
= &(extAttr
->vVersion
[0]);
14204 extAttr
->vListElements
[0].next
= &(extAttr
->vListElements
[1]);
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
);
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';
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;
14232 extAttr
->vVersion
[1].vPatch
= mfx
+ 2;
14234 extAttr
->vVersion
[1].vPatch
= mfx
+ 1;
14236 extAttr
->vVersion
[1].vString
[6] = ((char)(subtype
& 0xF)) + '0';
14237 extAttr
->vVersion
[1].vMajor
= (subtype
& 0x0F);
14239 extAttr
->vVersion
[1].vString
[5] = ((char)(subtype
& 0xF)) + '0';
14240 extAttr
->vVersion
[1].vMajor
+= 10 * subtype
;
14241 extAttr
->vVersion
[1].vString
[9] = 'A';
14243 extAttr
->vVersion
[1].vString
[10] = ((char)(mfx
& 0xF)) + '2';
14245 extAttr
->vVersion
[1].vString
[10] = ((char)(mfx
& 0xF)) + '1';
14248 extAttr
->vListElements
[1].version
= &(extAttr
->vVersion
[1]);
14249 extAttr
->vListElements
[1].next
= (pDRXVersionList_t
) (NULL
);
14251 *versionList
= &(extAttr
->vListElements
[0]);
14253 return (DRX_STS_OK
);
14256 *versionList
= (pDRXVersionList_t
) (NULL
);
14257 return (DRX_STS_ERROR
);
14261 /*============================================================================*/
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.
14271 * This funtion can be caled before open() and after close().
14275 static DRXStatus_t
CtrlProbeDevice(pDRXDemodInstance_t demod
)
14277 DRXPowerMode_t orgPowerMode
= DRX_POWER_UP
;
14278 DRXStatus_t retStatus
= DRX_STS_OK
;
14279 pDRXCommonAttr_t commonAttr
= (pDRXCommonAttr_t
) (NULL
);
14281 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
14283 if (commonAttr
->isOpened
== FALSE
14284 || commonAttr
->currentPowerMode
!= DRX_POWER_UP
) {
14285 pI2CDeviceAddr_t devAddr
= NULL
;
14286 DRXPowerMode_t powerMode
= DRX_POWER_UP
;
14289 devAddr
= demod
->myI2CDevAddr
;
14291 /* Remeber original power mode */
14292 orgPowerMode
= commonAttr
->currentPowerMode
;
14294 if (demod
->myCommonAttr
->isOpened
== FALSE
) {
14295 CHK_ERROR(PowerUpDevice(demod
));
14296 commonAttr
->currentPowerMode
= DRX_POWER_UP
;
14298 /* Wake-up device, feedback from device */
14299 CHK_ERROR(CtrlPowerMode(demod
, &powerMode
));
14301 /* Initialize HI, wakeup key especially */
14302 CHK_ERROR(InitHI(demod
));
14304 /* Check device id */
14305 RR32(devAddr
, SIO_TOP_JTAGID_LO__A
, &jtag
);
14306 jtag
= (jtag
>> 12) & 0xFFFF;
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 */
14318 /* ok , do nothing */
14321 retStatus
= DRX_STS_ERROR
;
14325 /* Device was not opened, return to orginal powermode,
14326 feedback from device */
14327 CHK_ERROR(CtrlPowerMode(demod
, &orgPowerMode
));
14329 /* dummy read to make this function fail in case device
14330 suddenly disappears after a succesful DRX_Open */
14334 return (retStatus
);
14337 commonAttr
->currentPowerMode
= orgPowerMode
;
14338 return (DRX_STS_ERROR
);
14341 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
14342 /*============================================================================*/
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
14352 Bool_t
IsMCBlockAudio(u32_t addr
)
14354 if ((addr
== AUD_XFP_PRAM_4K__A
) || (addr
== AUD_XDFP_PRAM_4K__A
)) {
14360 /*============================================================================*/
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.
14373 CtrlUCodeUpload(pDRXDemodInstance_t demod
,
14374 pDRXUCodeInfo_t mcInfo
,
14375 DRXUCodeAction_t action
, Bool_t uploadAudioMC
)
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
);
14384 devAddr
= demod
->myI2CDevAddr
;
14385 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14387 /* Check arguments */
14388 if ((mcInfo
== NULL
) ||
14389 (mcInfo
->mcData
== NULL
) || (mcInfo
->mcSize
== 0)) {
14390 return DRX_STS_INVALID_ARG
;
14393 mcData
= mcInfo
->mcData
;
14396 mcMagicWord
= UCodeRead16(mcData
);
14397 mcData
+= sizeof(u16_t
);
14398 mcNrOfBlks
= UCodeRead16(mcData
);
14399 mcData
+= sizeof(u16_t
);
14401 if ((mcMagicWord
!= DRXJ_UCODE_MAGIC_WORD
) || (mcNrOfBlks
== 0)) {
14402 /* wrong endianess or wrong data ? */
14403 return DRX_STS_INVALID_ARG
;
14406 /* Process microcode blocks */
14407 for (i
= 0; i
< mcNrOfBlks
; i
++) {
14408 DRXUCodeBlockHdr_t blockHdr
;
14409 u16_t mcBlockNrBytes
= 0;
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
);
14421 /* Check block header on:
14423 - data larger then 64Kb
14424 - if CRC enabled check CRC
14426 if ((blockHdr
.size
== 0) ||
14427 (blockHdr
.size
> 0x7FFF) ||
14428 (((blockHdr
.flags
& DRXJ_UCODE_CRC_FLAG
) != 0) &&
14429 (blockHdr
.CRC
!= UCodeComputeCRC(mcData
, blockHdr
.size
)))
14432 return DRX_STS_INVALID_ARG
;
14435 mcBlockNrBytes
= blockHdr
.size
* sizeof(u16_t
);
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
) {
14441 /*===================================================================*/
14444 /* Upload microcode */
14445 if (demod
->myAccessFunct
->
14446 writeBlockFunc(devAddr
,
14447 (DRXaddr_t
) blockHdr
.
14448 addr
, mcBlockNrBytes
,
14452 return (DRX_STS_ERROR
);
14457 /*===================================================================*/
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
;
14468 bytesLeftToCompare
= mcBlockNrBytes
;
14469 currAddr
= blockHdr
.addr
;
14472 while (bytesLeftToCompare
!= 0) {
14473 if (bytesLeftToCompare
>
14475 DRXJ_UCODE_MAX_BUF_SIZE
)) {
14478 DRXJ_UCODE_MAX_BUF_SIZE
);
14481 bytesLeftToCompare
;
14484 if (demod
->myAccessFunct
->
14485 readBlockFunc(devAddr
,
14493 return (DRX_STS_ERROR
);
14497 DRXBSP_HST_Memcmp(currPtr
,
14502 return (DRX_STS_ERROR
);
14507 (bytesToCompare
/ 2));
14509 &(currPtr
[bytesToCompare
]);
14510 bytesLeftToCompare
-=
14511 ((u32_t
) bytesToCompare
);
14512 } /* while( bytesToCompare > DRXJ_UCODE_MAX_BUF_SIZE ) */
14516 /*===================================================================*/
14518 return DRX_STS_INVALID_ARG
;
14521 } /* switch ( action ) */
14524 /* if( IsMCBlockAudio( blockHdr.addr ) == uploadAudioMC ) */
14526 mcData
+= mcBlockNrBytes
;
14527 } /* for( i = 0 ; i<mcNrOfBlks ; i++ ) */
14529 if (uploadAudioMC
== FALSE
) {
14530 extAttr
->flagAudMcUploaded
= FALSE
;
14533 return (DRX_STS_OK
);
14535 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
14537 /*============================================================================*/
14538 /*== CTRL Set/Get Config related functions ===================================*/
14539 /*============================================================================*/
14541 /*===== SigStrength() =========================================================*/
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.
14554 CtrlSigStrength(pDRXDemodInstance_t demod
, pu16_t sigStrength
)
14556 pDRXJData_t extAttr
= NULL
;
14557 DRXStandard_t standard
= DRX_STANDARD_UNKNOWN
;
14559 /* Check arguments */
14560 if ((sigStrength
== NULL
) || (demod
== NULL
)) {
14561 return (DRX_STS_INVALID_ARG
);
14564 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14565 standard
= extAttr
->standard
;
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
:
14576 CHK_ERROR(GetSigStrength(demod
, sigStrength
));
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
));
14589 case DRX_STANDARD_UNKNOWN
: /* fallthrough */
14591 return (DRX_STS_INVALID_ARG
);
14595 /* find out if signal strength is calculated in the same way for all standards */
14596 return (DRX_STS_OK
);
14598 return (DRX_STS_ERROR
);
14601 /*============================================================================*/
14603 * \fn DRXStatus_t CtrlGetCfgOOBMisc()
14604 * \brief Get current state information of OOB.
14605 * \param pointer to DRXJCfgOOBMisc_t.
14606 * \return DRXStatus_t.
14609 #ifndef DRXJ_DIGITAL_ONLY
14611 CtrlGetCfgOOBMisc(pDRXDemodInstance_t demod
, pDRXJCfgOOBMisc_t misc
)
14613 pI2CDeviceAddr_t devAddr
= NULL
;
14617 u16_t digitalAGCMant
= 0U;
14618 u16_t digitalAGCExp
= 0U;
14620 /* check arguments */
14621 if (misc
== NULL
) {
14622 return (DRX_STS_INVALID_ARG
);
14624 devAddr
= demod
->myI2CDevAddr
;
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
);
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
;
14637 SARR16(devAddr
, SCU_RAM_ORX_SCU_LOCK__A
, &lock
);
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
);
14646 SARR16(devAddr
, SCU_RAM_ORX_SCU_STATE__A
, &state
);
14647 misc
->state
= (state
>> 8) & 0xff;
14649 return (DRX_STS_OK
);
14651 return (DRX_STS_ERROR
);
14656 * \fn DRXStatus_t CtrlGetCfgVSBMisc()
14657 * \brief Get current state information of OOB.
14658 * \param pointer to DRXJCfgOOBMisc_t.
14659 * \return DRXStatus_t.
14663 CtrlGetCfgVSBMisc(pDRXDemodInstance_t demod
, pDRXJCfgVSBMisc_t misc
)
14665 pI2CDeviceAddr_t devAddr
= NULL
;
14667 /* check arguments */
14668 if (misc
== NULL
) {
14669 return (DRX_STS_INVALID_ARG
);
14671 devAddr
= demod
->myI2CDevAddr
;
14673 CHK_ERROR(GetVSBSymbErr(devAddr
, &misc
->symbError
));
14675 return (DRX_STS_OK
);
14677 return (DRX_STS_ERROR
);
14680 /*============================================================================*/
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.
14690 * Dispatch handling to standard specific function.
14694 CtrlSetCfgAgcIf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
14696 /* check arguments */
14697 if (agcSettings
== NULL
) {
14698 return (DRX_STS_INVALID_ARG
);
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 */
14707 return (DRX_STS_INVALID_ARG
);
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
:
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
:
14727 return SetAgcIf(demod
, agcSettings
, TRUE
);
14728 case DRX_STANDARD_UNKNOWN
:
14730 return (DRX_STS_INVALID_ARG
);
14733 return (DRX_STS_OK
);
14736 /*============================================================================*/
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.
14746 * Dispatch handling to standard specific function.
14750 CtrlGetCfgAgcIf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
14752 /* check arguments */
14753 if (agcSettings
== NULL
) {
14754 return (DRX_STS_INVALID_ARG
);
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
:
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
:
14774 return GetAgcIf(demod
, agcSettings
);
14775 case DRX_STANDARD_UNKNOWN
:
14777 return (DRX_STS_INVALID_ARG
);
14780 return (DRX_STS_OK
);
14783 /*============================================================================*/
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.
14793 * Dispatch handling to standard specific function.
14797 CtrlSetCfgAgcRf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
14799 /* check arguments */
14800 if (agcSettings
== NULL
) {
14801 return (DRX_STS_INVALID_ARG
);
14804 switch (agcSettings
->ctrlMode
) {
14805 case DRX_AGC_CTRL_AUTO
: /* fallthrough */
14806 case DRX_AGC_CTRL_USER
: /* fallthrough */
14807 case DRX_AGC_CTRL_OFF
:
14810 return (DRX_STS_INVALID_ARG
);
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
:
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
:
14830 return SetAgcRf(demod
, agcSettings
, TRUE
);
14831 case DRX_STANDARD_UNKNOWN
:
14833 return (DRX_STS_INVALID_ARG
);
14836 return (DRX_STS_OK
);
14839 /*============================================================================*/
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.
14849 * Dispatch handling to standard specific function.
14853 CtrlGetCfgAgcRf(pDRXDemodInstance_t demod
, pDRXJCfgAgc_t agcSettings
)
14855 /* check arguments */
14856 if (agcSettings
== NULL
) {
14857 return (DRX_STS_INVALID_ARG
);
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
:
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
:
14877 return GetAgcRf(demod
, agcSettings
);
14878 case DRX_STANDARD_UNKNOWN
:
14880 return (DRX_STS_INVALID_ARG
);
14883 return (DRX_STS_OK
);
14886 /*============================================================================*/
14889 * \fn DRXStatus_t CtrlGetCfgAgcInternal()
14890 * \brief Retrieve internal AGC value.
14891 * \param demod demod instance
14893 * \return DRXStatus_t.
14896 * Dispatch handling to standard specific function.
14900 CtrlGetCfgAgcInternal(pDRXDemodInstance_t demod
, pu16_t agcInternal
)
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;
14910 /* check arguments */
14911 if (agcInternal
== NULL
) {
14912 return (DRX_STS_INVALID_ARG
);
14914 devAddr
= demod
->myI2CDevAddr
;
14915 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14917 CHK_ERROR(CtrlLockStatus(demod
, &lockStatus
));
14918 if (lockStatus
!= DRXJ_DEMOD_LOCK
&& lockStatus
!= DRX_LOCKED
) {
14924 switch (extAttr
->standard
) {
14925 case DRX_STANDARD_8VSB
:
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
:
14939 case DRX_CONSTELLATION_QAM64
:
14943 return (DRX_STS_ERROR
);
14948 return (DRX_STS_INVALID_ARG
);
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);
14964 return (DRX_STS_OK
);
14966 return (DRX_STS_ERROR
);
14969 /*============================================================================*/
14972 * \fn DRXStatus_t CtrlSetCfgPreSaw()
14973 * \brief Set Pre-saw reference.
14974 * \param demod demod instance
14976 * \return DRXStatus_t.
14979 * Dispatch handling to standard specific function.
14983 CtrlSetCfgPreSaw(pDRXDemodInstance_t demod
, pDRXJCfgPreSaw_t preSaw
)
14985 pI2CDeviceAddr_t devAddr
= NULL
;
14986 pDRXJData_t extAttr
= NULL
;
14988 devAddr
= demod
->myI2CDevAddr
;
14989 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
14991 /* check arguments */
14992 if ((preSaw
== NULL
) || (preSaw
->reference
> IQM_AF_PDREF__M
)
14994 return (DRX_STS_INVALID_ARG
);
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
);
15006 /* Store pre-saw settings */
15007 switch (preSaw
->standard
) {
15008 case DRX_STANDARD_8VSB
:
15009 extAttr
->vsbPreSawCfg
= *preSaw
;
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
;
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
;
15030 return (DRX_STS_INVALID_ARG
);
15033 return (DRX_STS_OK
);
15035 return (DRX_STS_ERROR
);
15038 /*============================================================================*/
15041 * \fn DRXStatus_t CtrlSetCfgAfeGain()
15042 * \brief Set AFE Gain.
15043 * \param demod demod instance
15045 * \return DRXStatus_t.
15048 * Dispatch handling to standard specific function.
15052 CtrlSetCfgAfeGain(pDRXDemodInstance_t demod
, pDRXJCfgAfeGain_t afeGain
)
15054 pI2CDeviceAddr_t devAddr
= NULL
;
15055 pDRXJData_t extAttr
= NULL
;
15058 /* check arguments */
15059 if (afeGain
== NULL
) {
15060 return (DRX_STS_INVALID_ARG
);
15063 devAddr
= demod
->myI2CDevAddr
;
15064 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
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
:
15076 return (DRX_STS_INVALID_ARG
);
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 */
15082 if (afeGain
->gain
>= 329)
15084 else if (afeGain
->gain
<= 147)
15087 gain
= (afeGain
->gain
- 140 + 6) / 13;
15089 /* Only if standard is currently active */
15090 if (extAttr
->standard
== afeGain
->standard
)
15091 WR16(devAddr
, IQM_AF_PGA_GAIN__A
, gain
);
15093 /* Store AFE Gain settings */
15094 switch (afeGain
->standard
) {
15095 case DRX_STANDARD_8VSB
:
15096 extAttr
->vsbPgaCfg
= gain
* 13 + 140;
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;
15106 return (DRX_STS_ERROR
);
15109 return (DRX_STS_OK
);
15111 return (DRX_STS_ERROR
);
15114 /*============================================================================*/
15117 * \fn DRXStatus_t CtrlGetCfgPreSaw()
15118 * \brief Get Pre-saw reference setting.
15119 * \param demod demod instance
15121 * \return DRXStatus_t.
15124 * Dispatch handling to standard specific function.
15128 CtrlGetCfgPreSaw(pDRXDemodInstance_t demod
, pDRXJCfgPreSaw_t preSaw
)
15130 pI2CDeviceAddr_t devAddr
= NULL
;
15131 pDRXJData_t extAttr
= NULL
;
15133 /* check arguments */
15134 if (preSaw
== NULL
) {
15135 return (DRX_STS_INVALID_ARG
);
15138 devAddr
= demod
->myI2CDevAddr
;
15139 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
15141 switch (preSaw
->standard
) {
15142 case DRX_STANDARD_8VSB
:
15143 *preSaw
= extAttr
->vsbPreSawCfg
;
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
;
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
;
15162 case DRX_STANDARD_FM
:
15163 extAttr
->atvPreSawCfg
.standard
= DRX_STANDARD_FM
;
15164 *preSaw
= extAttr
->atvPreSawCfg
;
15168 return (DRX_STS_INVALID_ARG
);
15171 return (DRX_STS_OK
);
15174 /*============================================================================*/
15177 * \fn DRXStatus_t CtrlGetCfgAfeGain()
15178 * \brief Get AFE Gain.
15179 * \param demod demod instance
15181 * \return DRXStatus_t.
15184 * Dispatch handling to standard specific function.
15188 CtrlGetCfgAfeGain(pDRXDemodInstance_t demod
, pDRXJCfgAfeGain_t afeGain
)
15190 pI2CDeviceAddr_t devAddr
= NULL
;
15191 pDRXJData_t extAttr
= NULL
;
15193 /* check arguments */
15194 if (afeGain
== NULL
) {
15195 return (DRX_STS_INVALID_ARG
);
15198 devAddr
= demod
->myI2CDevAddr
;
15199 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
15201 switch (afeGain
->standard
) {
15202 case DRX_STANDARD_8VSB
:
15203 afeGain
->gain
= extAttr
->vsbPgaCfg
;
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
;
15213 return (DRX_STS_INVALID_ARG
);
15216 return (DRX_STS_OK
);
15219 /*============================================================================*/
15222 * \fn DRXStatus_t CtrlGetFecMeasSeqCount()
15223 * \brief Get FEC measurement sequnce number.
15224 * \param demod demod instance
15226 * \return DRXStatus_t.
15229 * Dispatch handling to standard specific function.
15233 CtrlGetFecMeasSeqCount(pDRXDemodInstance_t demod
, pu16_t fecMeasSeqCount
)
15235 /* check arguments */
15236 if (fecMeasSeqCount
== NULL
) {
15237 return (DRX_STS_INVALID_ARG
);
15240 RR16(demod
->myI2CDevAddr
, SCU_RAM_FEC_MEAS_COUNT__A
, fecMeasSeqCount
);
15242 return (DRX_STS_OK
);
15244 return (DRX_STS_ERROR
);
15247 /*============================================================================*/
15250 * \fn DRXStatus_t CtrlGetAccumCrRSCwErr()
15251 * \brief Get accumulative corrected RS codeword number.
15252 * \param demod demod instance
15254 * \return DRXStatus_t.
15257 * Dispatch handling to standard specific function.
15261 CtrlGetAccumCrRSCwErr(pDRXDemodInstance_t demod
, pu32_t accumCrRsCWErr
)
15263 if (accumCrRsCWErr
== NULL
) {
15264 return (DRX_STS_INVALID_ARG
);
15267 RR32(demod
->myI2CDevAddr
, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A
,
15270 return (DRX_STS_OK
);
15272 return (DRX_STS_ERROR
);
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.
15283 static DRXStatus_t
CtrlSetCfg(pDRXDemodInstance_t demod
, pDRXCfg_t config
)
15285 if (config
== NULL
) {
15286 return (DRX_STS_INVALID_ARG
);
15290 switch (config
->cfgType
) {
15291 case DRX_CFG_MPEG_OUTPUT
:
15292 return CtrlSetCfgMPEGOutput(demod
,
15293 (pDRXCfgMPEGOutput_t
) config
->
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
->
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
->
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
->
15327 case DRXJ_CFG_ATV_OUTPUT
:
15328 return CtrlSetCfgATVOutput(demod
,
15329 (pDRXJCfgAtvOutput_t
) config
->
15332 case DRXJ_CFG_MPEG_OUTPUT_MISC
:
15333 return CtrlSetCfgMpegOutputMisc(demod
,
15334 (pDRXJCfgMpegOutputMisc_t
)
15336 #ifndef DRXJ_EXCLUDE_AUDIO
15337 case DRX_CFG_AUD_VOLUME
:
15338 return AUDCtrlSetCfgVolume(demod
,
15339 (pDRXCfgAudVolume_t
) config
->
15341 case DRX_CFG_I2S_OUTPUT
:
15342 return AUDCtrlSetCfgOutputI2S(demod
,
15343 (pDRXCfgI2SOutput_t
) config
->
15345 case DRX_CFG_AUD_AUTOSOUND
:
15346 return AUDCtrSetlCfgAutoSound(demod
, (pDRXCfgAudAutoSound_t
)
15348 case DRX_CFG_AUD_ASS_THRES
:
15349 return AUDCtrlSetCfgASSThres(demod
, (pDRXCfgAudASSThres_t
)
15351 case DRX_CFG_AUD_CARRIER
:
15352 return AUDCtrlSetCfgCarrier(demod
,
15353 (pDRXCfgAudCarriers_t
) config
->
15355 case DRX_CFG_AUD_DEVIATION
:
15356 return AUDCtrlSetCfgDev(demod
,
15357 (pDRXCfgAudDeviation_t
) config
->
15359 case DRX_CFG_AUD_PRESCALE
:
15360 return AUDCtrlSetCfgPrescale(demod
,
15361 (pDRXCfgAudPrescale_t
) config
->
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
->
15373 return (DRX_STS_INVALID_ARG
);
15376 return (DRX_STS_OK
);
15378 return (DRX_STS_ERROR
);
15381 /*============================================================================*/
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.
15391 static DRXStatus_t
CtrlGetCfg(pDRXDemodInstance_t demod
, pDRXCfg_t config
)
15393 if (config
== NULL
) {
15394 return (DRX_STS_INVALID_ARG
);
15399 switch (config
->cfgType
) {
15400 case DRX_CFG_MPEG_OUTPUT
:
15401 return CtrlGetCfgMPEGOutput(demod
,
15402 (pDRXCfgMPEGOutput_t
) config
->
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
->
15438 case DRXJ_CFG_ATV_EQU_COEF
:
15439 return CtrlGetCfgAtvEquCoef(demod
,
15440 (pDRXJCfgAtvEquCoef_t
) config
->
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
->
15449 case DRXJ_CFG_ATV_AGC_STATUS
:
15450 return CtrlGetCfgAtvAgcStatus(demod
,
15451 (pDRXJCfgAtvAgcStatus_t
) config
->
15454 case DRXJ_CFG_MPEG_OUTPUT_MISC
:
15455 return CtrlGetCfgMpegOutputMisc(demod
,
15456 (pDRXJCfgMpegOutputMisc_t
)
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
->
15466 case DRX_CFG_I2S_OUTPUT
:
15467 return AUDCtrlGetCfgOutputI2S(demod
,
15468 (pDRXCfgI2SOutput_t
) config
->
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
->
15478 case DRX_CFG_AUD_ASS_THRES
:
15479 return AUDCtrlGetCfgASSThres(demod
,
15480 (pDRXCfgAudASSThres_t
) config
->
15482 case DRX_CFG_AUD_CARRIER
:
15483 return AUDCtrlGetCfgCarrier(demod
,
15484 (pDRXCfgAudCarriers_t
) config
->
15486 case DRX_CFG_AUD_DEVIATION
:
15487 return AUDCtrlGetCfgDev(demod
,
15488 (pDRXCfgAudDeviation_t
) config
->
15490 case DRX_CFG_AUD_PRESCALE
:
15491 return AUDCtrlGetCfgPrescale(demod
,
15492 (pDRXCfgAudPrescale_t
) config
->
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
->
15504 return (DRX_STS_INVALID_ARG
);
15507 return (DRX_STS_OK
);
15509 return (DRX_STS_ERROR
);
15512 /*=============================================================================
15513 ===== EXPORTED FUNCTIONS ====================================================*/
15516 * \brief Open the demod instance, configure device, configure drxdriver
15517 * \return Status_t Return status.
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.
15524 DRXStatus_t
DRXJ_Open(pDRXDemodInstance_t demod
)
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
;
15533 /* Check arguments */
15534 if (demod
->myExtAttr
== NULL
) {
15535 return (DRX_STS_INVALID_ARG
);
15538 devAddr
= demod
->myI2CDevAddr
;
15539 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
15540 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
15542 CHK_ERROR(PowerUpDevice(demod
));
15543 commonAttr
->currentPowerMode
= DRX_POWER_UP
;
15545 /* has to be in front of setIqmAf and setOrxNsuAox */
15546 CHK_ERROR(GetDeviceCapabilities(demod
));
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));
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
);
15559 CHK_ERROR(SetIqmAf(demod
, FALSE
));
15560 CHK_ERROR(SetOrxNsuAox(demod
, FALSE
));
15562 CHK_ERROR(InitHI(demod
));
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
));
15570 WR16(devAddr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_STOP
);
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
;
15580 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
15581 /* Upload microcode without audio part */
15582 CHK_ERROR(CtrlUCodeUpload
15583 (demod
, &ucodeInfo
, UCODE_UPLOAD
, FALSE
));
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
));
15593 (demod
, DRX_CTRL_VERIFY_UCODE
, &ucodeInfo
));
15594 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
15596 commonAttr
->isOpened
= FALSE
;
15599 /* Run SCU for a little while to initialize microcode version numbers */
15600 WR16(devAddr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_ACTIVE
);
15602 /* Open tuner instance */
15603 if (demod
->myTuner
!= NULL
) {
15604 demod
->myTuner
->myCommonAttr
->myUserData
= (void *)demod
;
15606 if (commonAttr
->tunerPortNr
== 1) {
15607 Bool_t bridgeClosed
= TRUE
;
15608 CHK_ERROR(CtrlI2CBridge(demod
, &bridgeClosed
));
15611 CHK_ERROR(DRXBSP_TUNER_Open(demod
->myTuner
));
15613 if (commonAttr
->tunerPortNr
== 1) {
15614 Bool_t bridgeClosed
= FALSE
;
15615 CHK_ERROR(CtrlI2CBridge(demod
, &bridgeClosed
));
15617 commonAttr
->tunerMinFreqRF
=
15618 ((demod
->myTuner
)->myCommonAttr
->minFreqRF
);
15619 commonAttr
->tunerMaxFreqRF
=
15620 ((demod
->myTuner
)->myCommonAttr
->maxFreqRF
);
15623 /* Initialize scan timeout */
15624 commonAttr
->scanDemodLockTimeout
= DRXJ_SCAN_TIMEOUT
;
15625 commonAttr
->scanDesiredLock
= DRX_LOCKED
;
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);
15635 extAttr
->vsbIfAgcCfg
.standard
= DRX_STANDARD_8VSB
;
15636 extAttr
->vsbIfAgcCfg
.ctrlMode
= DRX_AGC_CTRL_OFF
;
15637 extAttr
->vsbPgaCfg
= 140 + (11 * 13);
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;
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;
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
;
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
;
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
;
15698 extAttr
->standard
= DRX_STANDARD_UNKNOWN
;
15700 CHK_ERROR(SmartAntInit(demod
));
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
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));
15725 /* refresh the audio data structure with default */
15726 extAttr
->audData
= DRXJDefaultAudData_g
;
15728 return (DRX_STS_OK
);
15730 commonAttr
->isOpened
= FALSE
;
15731 return (DRX_STS_ERROR
);
15734 /*============================================================================*/
15737 * \brief Close the demod instance, power down the device
15738 * \return Status_t Return status.
15741 DRXStatus_t
DRXJ_Close(pDRXDemodInstance_t demod
)
15743 pI2CDeviceAddr_t devAddr
= NULL
;
15744 pDRXJData_t extAttr
= NULL
;
15745 pDRXCommonAttr_t commonAttr
= NULL
;
15746 DRXPowerMode_t powerMode
= DRX_POWER_UP
;
15748 commonAttr
= (pDRXCommonAttr_t
) demod
->myCommonAttr
;
15749 devAddr
= demod
->myI2CDevAddr
;
15750 extAttr
= (pDRXJData_t
) demod
->myExtAttr
;
15753 CHK_ERROR(CtrlPowerMode(demod
, &powerMode
));
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
));
15761 CHK_ERROR(DRXBSP_TUNER_Close(demod
->myTuner
));
15762 if (commonAttr
->tunerPortNr
== 1) {
15763 Bool_t bridgeClosed
= FALSE
;
15764 CHK_ERROR(CtrlI2CBridge(demod
, &bridgeClosed
));
15768 WR16(devAddr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_ACTIVE
);
15769 powerMode
= DRX_POWER_DOWN
;
15770 CHK_ERROR(CtrlPowerMode(demod
, &powerMode
));
15774 return (DRX_STS_ERROR
);
15777 /*============================================================================*/
15780 * \brief DRXJ specific control function
15781 * \return Status_t Return status.
15784 DRXJ_Ctrl(pDRXDemodInstance_t demod
, DRXCtrlIndex_t ctrl
, void *ctrlData
)
15787 /*======================================================================*/
15788 case DRX_CTRL_SET_CHANNEL
:
15790 return CtrlSetChannel(demod
, (pDRXChannel_t
) ctrlData
);
15793 /*======================================================================*/
15794 case DRX_CTRL_GET_CHANNEL
:
15796 return CtrlGetChannel(demod
, (pDRXChannel_t
) ctrlData
);
15799 /*======================================================================*/
15800 case DRX_CTRL_SIG_QUALITY
:
15802 return CtrlSigQuality(demod
,
15803 (pDRXSigQuality_t
) ctrlData
);
15806 /*======================================================================*/
15807 case DRX_CTRL_SIG_STRENGTH
:
15809 return CtrlSigStrength(demod
, (pu16_t
) ctrlData
);
15812 /*======================================================================*/
15813 case DRX_CTRL_CONSTEL
:
15815 return CtrlConstel(demod
, (pDRXComplex_t
) ctrlData
);
15818 /*======================================================================*/
15819 case DRX_CTRL_SET_CFG
:
15821 return CtrlSetCfg(demod
, (pDRXCfg_t
) ctrlData
);
15824 /*======================================================================*/
15825 case DRX_CTRL_GET_CFG
:
15827 return CtrlGetCfg(demod
, (pDRXCfg_t
) ctrlData
);
15830 /*======================================================================*/
15831 case DRX_CTRL_I2C_BRIDGE
:
15833 return CtrlI2CBridge(demod
, (pBool_t
) ctrlData
);
15836 /*======================================================================*/
15837 case DRX_CTRL_LOCK_STATUS
:
15839 return CtrlLockStatus(demod
,
15840 (pDRXLockStatus_t
) ctrlData
);
15843 /*======================================================================*/
15844 case DRX_CTRL_SET_STANDARD
:
15846 return CtrlSetStandard(demod
,
15847 (pDRXStandard_t
) ctrlData
);
15850 /*======================================================================*/
15851 case DRX_CTRL_GET_STANDARD
:
15853 return CtrlGetStandard(demod
,
15854 (pDRXStandard_t
) ctrlData
);
15857 /*======================================================================*/
15858 case DRX_CTRL_POWER_MODE
:
15860 return CtrlPowerMode(demod
, (pDRXPowerMode_t
) ctrlData
);
15863 /*======================================================================*/
15864 case DRX_CTRL_VERSION
:
15866 return CtrlVersion(demod
,
15867 (pDRXVersionList_t
*) ctrlData
);
15870 /*======================================================================*/
15871 case DRX_CTRL_PROBE_DEVICE
:
15873 return CtrlProbeDevice(demod
);
15876 /*======================================================================*/
15877 case DRX_CTRL_SET_OOB
:
15879 return CtrlSetOOB(demod
, (pDRXOOB_t
) ctrlData
);
15882 /*======================================================================*/
15883 case DRX_CTRL_GET_OOB
:
15885 return CtrlGetOOB(demod
, (pDRXOOBStatus_t
) ctrlData
);
15888 /*======================================================================*/
15889 case DRX_CTRL_SET_UIO_CFG
:
15891 return CtrlSetUIOCfg(demod
, (pDRXUIOCfg_t
) ctrlData
);
15894 /*======================================================================*/
15895 case DRX_CTRL_GET_UIO_CFG
:
15897 return CtrlGetUIOCfg(demod
, (pDRXUIOCfg_t
) ctrlData
);
15900 /*======================================================================*/
15901 case DRX_CTRL_UIO_READ
:
15903 return CtrlUIORead(demod
, (pDRXUIOData_t
) ctrlData
);
15906 /*======================================================================*/
15907 case DRX_CTRL_UIO_WRITE
:
15909 return CtrlUIOWrite(demod
, (pDRXUIOData_t
) ctrlData
);
15912 /*======================================================================*/
15913 case DRX_CTRL_AUD_SET_STANDARD
:
15915 return AUDCtrlSetStandard(demod
,
15916 (pDRXAudStandard_t
) ctrlData
);
15919 /*======================================================================*/
15920 case DRX_CTRL_AUD_GET_STANDARD
:
15922 return AUDCtrlGetStandard(demod
,
15923 (pDRXAudStandard_t
) ctrlData
);
15926 /*======================================================================*/
15927 case DRX_CTRL_AUD_GET_STATUS
:
15929 return AUDCtrlGetStatus(demod
,
15930 (pDRXAudStatus_t
) ctrlData
);
15933 /*======================================================================*/
15934 case DRX_CTRL_AUD_BEEP
:
15936 return AUDCtrlBeep(demod
, (pDRXAudBeep_t
) ctrlData
);
15940 /*======================================================================*/
15941 case DRX_CTRL_I2C_READWRITE
:
15943 return CtrlI2CWriteRead(demod
,
15944 (pDRXI2CData_t
) ctrlData
);
15947 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
15948 case DRX_CTRL_LOAD_UCODE
:
15950 return CtrlUCodeUpload(demod
,
15951 (pDRXUCodeInfo_t
) ctrlData
,
15952 UCODE_UPLOAD
, FALSE
);
15955 case DRX_CTRL_VERIFY_UCODE
:
15957 return CtrlUCodeUpload(demod
,
15958 (pDRXUCodeInfo_t
) ctrlData
,
15959 UCODE_VERIFY
, FALSE
);
15962 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
15963 case DRX_CTRL_VALIDATE_UCODE
:
15965 return CtrlValidateUCode(demod
);
15969 return (DRX_STS_FUNC_NOT_AVAILABLE
);
15971 return (DRX_STS_OK
);