38b2df95c5
Add support for the Trident DRX-J driver, including a card profile for the PCTV 80e which uses the chip. Thanks to Trident for allowing the release of this code under a BSD license, and of course Hauppauge/PCTV for pushing for its release to the community. [pdickeybeta@gmail.com: modified to fix compilation errors and also to move the driver files from the drx39xy subdirectory to the frontends directory] [m.chehab@samsung.com: fix merge conflicts, commented drx-j compilation and added EM28XX_R06_I2C_CLK setup also to the board setup] Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
16681 lines
509 KiB
C
16681 lines
509 KiB
C
/**
|
|
* \file $Id: drxj.c,v 1.637 2010/01/18 17:21:10 dingtao Exp $
|
|
*
|
|
* \brief DRXJ specific implementation of DRX driver
|
|
*
|
|
* \author Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
|
|
*/
|
|
|
|
/*
|
|
* $(c) 2006-2010 Trident Microsystems, Inc. - All rights reserved.
|
|
*
|
|
* This software and related documentation (the 'Software') are intellectual
|
|
* property owned by Trident and are copyright of Trident, unless specifically
|
|
* noted otherwise.
|
|
*
|
|
* Any use of the Software is permitted only pursuant to the terms of the
|
|
* license agreement, if any, which accompanies, is included with or applicable
|
|
* to the Software ('License Agreement') or upon express written consent of
|
|
* Trident. Any copying, reproduction or redistribution of the Software in
|
|
* whole or in part by any means not in accordance with the License Agreement
|
|
* or as agreed in writing by Trident is expressly prohibited.
|
|
*
|
|
* THE SOFTWARE IS WARRANTED, IF AT ALL, ONLY ACCORDING TO THE TERMS OF THE
|
|
* LICENSE AGREEMENT. EXCEPT AS WARRANTED IN THE LICENSE AGREEMENT THE SOFTWARE
|
|
* IS DELIVERED 'AS IS' AND TRIDENT HEREBY DISCLAIMS ALL WARRANTIES AND
|
|
* CONDITIONS WITH REGARD TO THE SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
|
* AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIT
|
|
* ENJOYMENT, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL
|
|
* PROPERTY OR OTHER RIGHTS WHICH MAY RESULT FROM THE USE OR THE INABILITY
|
|
* TO USE THE SOFTWARE.
|
|
*
|
|
* IN NO EVENT SHALL TRIDENT BE LIABLE FOR INDIRECT, INCIDENTAL, CONSEQUENTIAL,
|
|
* PUNITIVE, SPECIAL OR OTHER DAMAGES WHATSOEVER INCLUDING WITHOUT LIMITATION,
|
|
* DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
|
|
* INFORMATION, AND THE LIKE, ARISING OUT OF OR RELATING TO THE USE OF OR THE
|
|
* INABILITY TO USE THE SOFTWARE, EVEN IF TRIDENT HAS BEEN ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGES, EXCEPT PERSONAL INJURY OR DEATH RESULTING FROM
|
|
* TRIDENT'S NEGLIGENCE. $
|
|
*
|
|
*/
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
INCLUDE FILES
|
|
----------------------------------------------------------------------------*/
|
|
|
|
#include "drxj.h"
|
|
#include "drxj_map.h"
|
|
|
|
#ifdef DRXJ_OPTIONS_H
|
|
#include "drxj_options.h"
|
|
#endif
|
|
|
|
|
|
/*============================================================================*/
|
|
/*=== DEFINES ================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \brief Maximum u32_t value.
|
|
*/
|
|
#ifndef MAX_U32
|
|
#define MAX_U32 ((u32_t) (0xFFFFFFFFL))
|
|
#endif
|
|
|
|
/* Customer configurable hardware settings, etc */
|
|
#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
|
|
#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
|
|
#endif
|
|
|
|
#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
|
|
#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
|
|
#endif
|
|
|
|
#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
|
|
#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
|
|
#endif
|
|
|
|
#ifndef OOB_CRX_DRIVE_STRENGTH
|
|
#define OOB_CRX_DRIVE_STRENGTH 0x02
|
|
#endif
|
|
|
|
#ifndef OOB_DRX_DRIVE_STRENGTH
|
|
#define OOB_DRX_DRIVE_STRENGTH 0x02
|
|
#endif
|
|
/**** START DJCOMBO patches to DRXJ registermap constants *********************/
|
|
/**** registermap 200706071303 from drxj **************************************/
|
|
#define ATV_TOP_CR_AMP_TH_FM 0x0
|
|
#define ATV_TOP_CR_AMP_TH_L 0xA
|
|
#define ATV_TOP_CR_AMP_TH_LP 0xA
|
|
#define ATV_TOP_CR_AMP_TH_BG 0x8
|
|
#define ATV_TOP_CR_AMP_TH_DK 0x8
|
|
#define ATV_TOP_CR_AMP_TH_I 0x8
|
|
#define ATV_TOP_CR_CONT_CR_D_MN 0x18
|
|
#define ATV_TOP_CR_CONT_CR_D_FM 0x0
|
|
#define ATV_TOP_CR_CONT_CR_D_L 0x20
|
|
#define ATV_TOP_CR_CONT_CR_D_LP 0x20
|
|
#define ATV_TOP_CR_CONT_CR_D_BG 0x18
|
|
#define ATV_TOP_CR_CONT_CR_D_DK 0x18
|
|
#define ATV_TOP_CR_CONT_CR_D_I 0x18
|
|
#define ATV_TOP_CR_CONT_CR_I_MN 0x80
|
|
#define ATV_TOP_CR_CONT_CR_I_FM 0x0
|
|
#define ATV_TOP_CR_CONT_CR_I_L 0x80
|
|
#define ATV_TOP_CR_CONT_CR_I_LP 0x80
|
|
#define ATV_TOP_CR_CONT_CR_I_BG 0x80
|
|
#define ATV_TOP_CR_CONT_CR_I_DK 0x80
|
|
#define ATV_TOP_CR_CONT_CR_I_I 0x80
|
|
#define ATV_TOP_CR_CONT_CR_P_MN 0x4
|
|
#define ATV_TOP_CR_CONT_CR_P_FM 0x0
|
|
#define ATV_TOP_CR_CONT_CR_P_L 0x4
|
|
#define ATV_TOP_CR_CONT_CR_P_LP 0x4
|
|
#define ATV_TOP_CR_CONT_CR_P_BG 0x4
|
|
#define ATV_TOP_CR_CONT_CR_P_DK 0x4
|
|
#define ATV_TOP_CR_CONT_CR_P_I 0x4
|
|
#define ATV_TOP_CR_OVM_TH_MN 0xA0
|
|
#define ATV_TOP_CR_OVM_TH_FM 0x0
|
|
#define ATV_TOP_CR_OVM_TH_L 0xA0
|
|
#define ATV_TOP_CR_OVM_TH_LP 0xA0
|
|
#define ATV_TOP_CR_OVM_TH_BG 0xA0
|
|
#define ATV_TOP_CR_OVM_TH_DK 0xA0
|
|
#define ATV_TOP_CR_OVM_TH_I 0xA0
|
|
#define ATV_TOP_EQU0_EQU_C0_FM 0x0
|
|
#define ATV_TOP_EQU0_EQU_C0_L 0x3
|
|
#define ATV_TOP_EQU0_EQU_C0_LP 0x3
|
|
#define ATV_TOP_EQU0_EQU_C0_BG 0x7
|
|
#define ATV_TOP_EQU0_EQU_C0_DK 0x0
|
|
#define ATV_TOP_EQU0_EQU_C0_I 0x3
|
|
#define ATV_TOP_EQU1_EQU_C1_FM 0x0
|
|
#define ATV_TOP_EQU1_EQU_C1_L 0x1F6
|
|
#define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
|
|
#define ATV_TOP_EQU1_EQU_C1_BG 0x197
|
|
#define ATV_TOP_EQU1_EQU_C1_DK 0x198
|
|
#define ATV_TOP_EQU1_EQU_C1_I 0x1F6
|
|
#define ATV_TOP_EQU2_EQU_C2_FM 0x0
|
|
#define ATV_TOP_EQU2_EQU_C2_L 0x28
|
|
#define ATV_TOP_EQU2_EQU_C2_LP 0x28
|
|
#define ATV_TOP_EQU2_EQU_C2_BG 0xC5
|
|
#define ATV_TOP_EQU2_EQU_C2_DK 0xB0
|
|
#define ATV_TOP_EQU2_EQU_C2_I 0x28
|
|
#define ATV_TOP_EQU3_EQU_C3_FM 0x0
|
|
#define ATV_TOP_EQU3_EQU_C3_L 0x192
|
|
#define ATV_TOP_EQU3_EQU_C3_LP 0x192
|
|
#define ATV_TOP_EQU3_EQU_C3_BG 0x12E
|
|
#define ATV_TOP_EQU3_EQU_C3_DK 0x18E
|
|
#define ATV_TOP_EQU3_EQU_C3_I 0x192
|
|
#define ATV_TOP_STD_MODE_MN 0x0
|
|
#define ATV_TOP_STD_MODE_FM 0x1
|
|
#define ATV_TOP_STD_MODE_L 0x0
|
|
#define ATV_TOP_STD_MODE_LP 0x0
|
|
#define ATV_TOP_STD_MODE_BG 0x0
|
|
#define ATV_TOP_STD_MODE_DK 0x0
|
|
#define ATV_TOP_STD_MODE_I 0x0
|
|
#define ATV_TOP_STD_VID_POL_MN 0x0
|
|
#define ATV_TOP_STD_VID_POL_FM 0x0
|
|
#define ATV_TOP_STD_VID_POL_L 0x2
|
|
#define ATV_TOP_STD_VID_POL_LP 0x2
|
|
#define ATV_TOP_STD_VID_POL_BG 0x0
|
|
#define ATV_TOP_STD_VID_POL_DK 0x0
|
|
#define ATV_TOP_STD_VID_POL_I 0x0
|
|
#define ATV_TOP_VID_AMP_MN 0x380
|
|
#define ATV_TOP_VID_AMP_FM 0x0
|
|
#define ATV_TOP_VID_AMP_L 0xF50
|
|
#define ATV_TOP_VID_AMP_LP 0xF50
|
|
#define ATV_TOP_VID_AMP_BG 0x380
|
|
#define ATV_TOP_VID_AMP_DK 0x394
|
|
#define ATV_TOP_VID_AMP_I 0x3D8
|
|
#define IQM_CF_OUT_ENA_OFDM__M 0x4
|
|
#define IQM_FS_ADJ_SEL_B_QAM 0x1
|
|
#define IQM_FS_ADJ_SEL_B_OFF 0x0
|
|
#define IQM_FS_ADJ_SEL_B_VSB 0x2
|
|
#define IQM_RC_ADJ_SEL_B_OFF 0x0
|
|
#define IQM_RC_ADJ_SEL_B_QAM 0x1
|
|
#define IQM_RC_ADJ_SEL_B_VSB 0x2
|
|
/**** END DJCOMBO patches to DRXJ registermap *********************************/
|
|
|
|
#include "drx_driver_version.h"
|
|
|
|
//#define DRX_DEBUG
|
|
#ifdef DRX_DEBUG
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
ENUMS
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
DEFINES
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef DRXJ_WAKE_UP_KEY
|
|
#define DRXJ_WAKE_UP_KEY (demod -> myI2CDevAddr -> i2cAddr)
|
|
#endif
|
|
|
|
/**
|
|
* \def DRXJ_DEF_I2C_ADDR
|
|
* \brief Default I2C addres of a demodulator instance.
|
|
*/
|
|
#define DRXJ_DEF_I2C_ADDR (0x52)
|
|
|
|
/**
|
|
* \def DRXJ_DEF_DEMOD_DEV_ID
|
|
* \brief Default device identifier of a demodultor instance.
|
|
*/
|
|
#define DRXJ_DEF_DEMOD_DEV_ID (1)
|
|
|
|
/**
|
|
* \def DRXJ_SCAN_TIMEOUT
|
|
* \brief Timeout value for waiting on demod lock during channel scan (millisec).
|
|
*/
|
|
#define DRXJ_SCAN_TIMEOUT 1000
|
|
|
|
/**
|
|
* \def DRXJ_DAP
|
|
* \brief Name of structure containing all data access protocol functions.
|
|
*/
|
|
#define DRXJ_DAP drxDapDRXJFunct_g
|
|
|
|
/**
|
|
* \def HI_I2C_DELAY
|
|
* \brief HI timing delay for I2C timing (in nano seconds)
|
|
*
|
|
* Used to compute HI_CFG_DIV
|
|
*/
|
|
#define HI_I2C_DELAY 42
|
|
|
|
/**
|
|
* \def HI_I2C_BRIDGE_DELAY
|
|
* \brief HI timing delay for I2C timing (in nano seconds)
|
|
*
|
|
* Used to compute HI_CFG_BDL
|
|
*/
|
|
#define HI_I2C_BRIDGE_DELAY 750
|
|
|
|
/**
|
|
* \brief Time Window for MER and SER Measurement in Units of Segment duration.
|
|
*/
|
|
#define VSB_TOP_MEASUREMENT_PERIOD 64
|
|
#define SYMBOLS_PER_SEGMENT 832
|
|
|
|
/**
|
|
* \brief bit rate and segment rate constants used for SER and BER.
|
|
*/
|
|
/* values taken from the QAM microcode */
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
|
|
#define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
|
|
#define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
|
|
/**
|
|
* \brief Min supported symbolrates.
|
|
*/
|
|
#ifndef DRXJ_QAM_SYMBOLRATE_MIN
|
|
#define DRXJ_QAM_SYMBOLRATE_MIN (520000)
|
|
#endif
|
|
|
|
/**
|
|
* \brief Max supported symbolrates.
|
|
*/
|
|
#ifndef DRXJ_QAM_SYMBOLRATE_MAX
|
|
#define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
|
|
#endif
|
|
|
|
/**
|
|
* \def DRXJ_QAM_MAX_WAITTIME
|
|
* \brief Maximal wait time for QAM auto constellation in ms
|
|
*/
|
|
#ifndef DRXJ_QAM_MAX_WAITTIME
|
|
#define DRXJ_QAM_MAX_WAITTIME 900
|
|
#endif
|
|
|
|
#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
|
|
#define DRXJ_QAM_FEC_LOCK_WAITTIME 150
|
|
#endif
|
|
|
|
#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
|
|
#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
|
|
#endif
|
|
|
|
/**
|
|
* \def SCU status and results
|
|
* \brief SCU
|
|
*/
|
|
#define DRX_SCU_READY 0
|
|
#define DRXJ_MAX_WAITTIME 100 /* ms */
|
|
#define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
|
|
#define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
|
|
|
|
/**
|
|
* \def DRX_AUD_MAX_DEVIATION
|
|
* \brief Needed for calculation of prescale feature in AUD
|
|
*/
|
|
#ifndef DRXJ_AUD_MAX_FM_DEVIATION
|
|
#define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
|
|
#endif
|
|
|
|
/**
|
|
* \brief Needed for calculation of NICAM prescale feature in AUD
|
|
*/
|
|
#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
|
|
#define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
|
|
#endif
|
|
|
|
/**
|
|
* \brief Needed for calculation of NICAM prescale feature in AUD
|
|
*/
|
|
#ifndef DRXJ_AUD_MAX_WAITTIME
|
|
#define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
|
|
#endif
|
|
|
|
/* ATV config changed flags */
|
|
#define DRXJ_ATV_CHANGED_COEF ( 0x00000001UL )
|
|
#define DRXJ_ATV_CHANGED_PEAK_FLT ( 0x00000008UL )
|
|
#define DRXJ_ATV_CHANGED_NOISE_FLT ( 0x00000010UL )
|
|
#define DRXJ_ATV_CHANGED_OUTPUT ( 0x00000020UL )
|
|
#define DRXJ_ATV_CHANGED_SIF_ATT ( 0x00000040UL )
|
|
|
|
/* UIO define */
|
|
#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
|
|
#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
/*============================================================================*/
|
|
/*=== MICROCODE RELATED DEFINES ==============================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \def DRXJ_UCODE_MAGIC_WORD
|
|
* \brief Magic word for checking correct Endianess of microcode data.
|
|
*
|
|
*/
|
|
|
|
#ifndef DRXJ_UCODE_MAGIC_WORD
|
|
#define DRXJ_UCODE_MAGIC_WORD ((((u16_t)'H')<<8)+((u16_t)'L'))
|
|
#endif
|
|
|
|
/**
|
|
* \def DRXJ_UCODE_CRC_FLAG
|
|
* \brief CRC flag in ucode header, flags field.
|
|
*
|
|
*/
|
|
|
|
#ifndef DRXJ_UCODE_CRC_FLAG
|
|
#define DRXJ_UCODE_CRC_FLAG (0x0001)
|
|
#endif
|
|
|
|
/**
|
|
* \def DRXJ_UCODE_COMPRESSION_FLAG
|
|
* \brief Compression flag in ucode header, flags field.
|
|
*
|
|
*/
|
|
|
|
#ifndef DRXJ_UCODE_COMPRESSION_FLAG
|
|
#define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
|
|
#endif
|
|
|
|
/**
|
|
* \def DRXJ_UCODE_MAX_BUF_SIZE
|
|
* \brief Maximum size of buffer used to verify the microcode.Must be an even number.
|
|
*
|
|
*/
|
|
|
|
#ifndef DRXJ_UCODE_MAX_BUF_SIZE
|
|
#define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
|
|
#endif
|
|
#if DRXJ_UCODE_MAX_BUF_SIZE & 1
|
|
#error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
|
|
#endif
|
|
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
/* Pin safe mode macro */
|
|
#define DRXJ_PIN_SAFE_MODE 0x0000
|
|
/*============================================================================*/
|
|
/*=== GLOBAL VARIABLEs =======================================================*/
|
|
/*============================================================================*/
|
|
/**
|
|
*/
|
|
|
|
/**
|
|
* \brief Temporary register definitions.
|
|
* (register definitions that are not yet available in register master)
|
|
*/
|
|
|
|
/******************************************************************************/
|
|
/* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
|
|
/* RAM adresses directly. This must be READ ONLY to avoid problems. */
|
|
/* Writing to the interface adresses is more than only writing the RAM */
|
|
/* locations */
|
|
/******************************************************************************/
|
|
/**
|
|
* \brief RAM location of MODUS registers
|
|
*/
|
|
#define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
|
|
#define AUD_DEM_RAM_MODUS_HI__M 0xF000
|
|
|
|
#define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
|
|
#define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
|
|
|
|
/**
|
|
* \brief RAM location of I2S config registers
|
|
*/
|
|
#define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
|
|
#define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
|
|
|
|
/**
|
|
* \brief RAM location of DCO config registers
|
|
*/
|
|
#define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
|
|
#define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
|
|
#define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
|
|
#define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
|
|
|
|
/**
|
|
* \brief RAM location of Threshold registers
|
|
*/
|
|
#define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
|
|
#define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
|
|
#define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
|
|
|
|
/**
|
|
* \brief RAM location of Carrier Threshold registers
|
|
*/
|
|
#define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
|
|
#define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
|
|
|
|
/**
|
|
* \brief FM Matrix register fix
|
|
*/
|
|
#ifdef AUD_DEM_WR_FM_MATRIX__A
|
|
#undef AUD_DEM_WR_FM_MATRIX__A
|
|
#endif
|
|
#define AUD_DEM_WR_FM_MATRIX__A 0x105006F
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Defines required for audio
|
|
*/
|
|
#define AUD_VOLUME_ZERO_DB 115
|
|
#define AUD_VOLUME_DB_MIN -60
|
|
#define AUD_VOLUME_DB_MAX 12
|
|
#define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
|
|
#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
|
|
#define AUD_MAX_AVC_REF_LEVEL 15
|
|
#define AUD_I2S_FREQUENCY_MAX 48000UL
|
|
#define AUD_I2S_FREQUENCY_MIN 12000UL
|
|
#define AUD_RDS_ARRAY_SIZE 18
|
|
|
|
/**
|
|
* \brief Needed for calculation of prescale feature in AUD
|
|
*/
|
|
#ifndef DRX_AUD_MAX_FM_DEVIATION
|
|
#define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
|
|
#endif
|
|
|
|
/**
|
|
* \brief Needed for calculation of NICAM prescale feature in AUD
|
|
*/
|
|
#ifndef DRX_AUD_MAX_NICAM_PRESCALE
|
|
#define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
|
|
#endif
|
|
|
|
|
|
/*============================================================================*/
|
|
/* Values for I2S Master/Slave pin configurations */
|
|
#define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
|
|
#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
|
|
#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
|
|
#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
|
|
|
|
#define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
|
|
#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
|
|
#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
|
|
#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
|
|
|
|
#define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
|
|
#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
|
|
#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
|
|
#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
|
|
|
|
/*============================================================================*/
|
|
/*=== REGISTER ACCESS MACROS =================================================*/
|
|
/*============================================================================*/
|
|
|
|
#ifdef DRXJDRIVER_DEBUG
|
|
#include <stdio.h>
|
|
#define CHK_ERROR( s ) \
|
|
do{ \
|
|
if ( (s) != DRX_STS_OK ) \
|
|
{ \
|
|
fprintf(stderr, \
|
|
"ERROR[\n file : %s\n line : %d\n]\n", \
|
|
__FILE__,__LINE__); \
|
|
goto rw_error; }; \
|
|
} \
|
|
while (0 != 0)
|
|
#else
|
|
#define CHK_ERROR( s ) \
|
|
do{ \
|
|
if ( (s) != DRX_STS_OK ) { goto rw_error; } \
|
|
} while (0 != 0)
|
|
#endif
|
|
|
|
#define CHK_ZERO( s ) \
|
|
do{ \
|
|
if ( (s) == 0 ) return DRX_STS_ERROR; \
|
|
} while (0)
|
|
|
|
#define DUMMY_READ() \
|
|
do{ \
|
|
u16_t dummy; \
|
|
RR16( demod->myI2CDevAddr, SCU_RAM_VERSION_HI__A, &dummy ); \
|
|
} while (0)
|
|
|
|
#define WR16( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), 0 ) )
|
|
|
|
#define RR16( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP.readReg16Func( (dev), (addr), (val), 0 ) )
|
|
|
|
#define WR32( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP.writeReg32Func( (dev), (addr), (val), 0 ) )
|
|
|
|
#define RR32( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP.readReg32Func( (dev), (addr), (val), 0 ) )
|
|
|
|
#define WRB( dev, addr, len, block ) \
|
|
CHK_ERROR( DRXJ_DAP.writeBlockFunc( (dev), (addr), (len), (block), 0 ) )
|
|
|
|
#define RRB( dev, addr, len, block ) \
|
|
CHK_ERROR( DRXJ_DAP.readBlockFunc( (dev), (addr), (len), (block), 0 ) )
|
|
|
|
#define BCWR16( dev, addr, val ) \
|
|
CHK_ERROR( DRXJ_DAP.writeReg16Func( (dev), (addr), (val), DRXDAP_FASI_BROADCAST ) )
|
|
|
|
#define ARR32( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP_AtomicReadReg32( (dev), (addr), (val), 0 ) )
|
|
|
|
#define SARR16( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP_SCU_AtomicReadReg16( (dev), (addr), (val), 0 ) )
|
|
|
|
#define SAWR16( dev, addr, val) \
|
|
CHK_ERROR( DRXJ_DAP_SCU_AtomicWriteReg16( (dev), (addr), (val), 0 ) )
|
|
|
|
/**
|
|
* This macro is used to create byte arrays for block writes.
|
|
* Block writes speed up I2C traffic between host and demod.
|
|
* The macro takes care of the required byte order in a 16 bits word.
|
|
* x -> lowbyte(x), highbyte(x)
|
|
*/
|
|
#define DRXJ_16TO8( x ) ((u8_t) (((u16_t)x) &0xFF)), \
|
|
((u8_t)((((u16_t)x)>>8)&0xFF))
|
|
/**
|
|
* This macro is used to convert byte array to 16 bit register value for block read.
|
|
* Block read speed up I2C traffic between host and demod.
|
|
* The macro takes care of the required byte order in a 16 bits word.
|
|
*/
|
|
#define DRXJ_8TO16( x ) ((u16_t) (x[0] | (x[1] << 8)))
|
|
|
|
/*============================================================================*/
|
|
/*=== MISC DEFINES ===========================================================*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*=== HI COMMAND RELATED DEFINES =============================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \brief General maximum number of retries for ucode command interfaces
|
|
*/
|
|
#define DRXJ_MAX_RETRIES (100)
|
|
|
|
/*============================================================================*/
|
|
/*=== STANDARD RELATED MACROS ================================================*/
|
|
/*============================================================================*/
|
|
|
|
#define DRXJ_ISATVSTD( std ) ( ( std == DRX_STANDARD_PAL_SECAM_BG ) || \
|
|
( std == DRX_STANDARD_PAL_SECAM_DK ) || \
|
|
( std == DRX_STANDARD_PAL_SECAM_I ) || \
|
|
( std == DRX_STANDARD_PAL_SECAM_L ) || \
|
|
( std == DRX_STANDARD_PAL_SECAM_LP ) || \
|
|
( std == DRX_STANDARD_NTSC ) || \
|
|
( std == DRX_STANDARD_FM ) )
|
|
|
|
#define DRXJ_ISQAMSTD( std ) ( ( std == DRX_STANDARD_ITU_A ) || \
|
|
( std == DRX_STANDARD_ITU_B ) || \
|
|
( std == DRX_STANDARD_ITU_C ) || \
|
|
( std == DRX_STANDARD_ITU_D ))
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
STATIC VARIABLES
|
|
----------------------------------------------------------------------------*/
|
|
DRXStatus_t DRXJ_Open ( pDRXDemodInstance_t demod );
|
|
DRXStatus_t DRXJ_Close ( pDRXDemodInstance_t demod);
|
|
DRXStatus_t DRXJ_Ctrl ( pDRXDemodInstance_t demod,
|
|
DRXCtrlIndex_t ctrl,
|
|
void *ctrlData);
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
GLOBAL VARIABLES
|
|
----------------------------------------------------------------------------*/
|
|
/*
|
|
* DRXJ DAP structures
|
|
*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize,
|
|
pu8_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u8_t wdata,
|
|
pu8_t rdata);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u16_t wdata,
|
|
pu16_t rdata);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u32_t wdata,
|
|
pu32_t rdata);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu8_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu16_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu32_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize,
|
|
pu8_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u8_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t data,
|
|
DRXflags_t flags);
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u32_t data,
|
|
DRXflags_t flags);
|
|
|
|
/* The version structure of this protocol implementation */
|
|
char drxDapDRXJModuleName[] = "DRXJ Data Access Protocol";
|
|
char drxDapDRXJVersionText[] = "0.0.0";
|
|
|
|
DRXVersion_t drxDapDRXJVersion = {
|
|
DRX_MODULE_DAP, /**< type identifier of the module */
|
|
drxDapDRXJModuleName, /**< name or description of module */
|
|
|
|
0, /**< major version number */
|
|
0, /**< minor version number */
|
|
0, /**< patch version number */
|
|
drxDapDRXJVersionText /**< version as text string */
|
|
};
|
|
|
|
/* The structure containing the protocol interface */
|
|
DRXAccessFunc_t drxDapDRXJFunct_g = {
|
|
&drxDapDRXJVersion,
|
|
DRXJ_DAP_WriteBlock, /* Supported */
|
|
DRXJ_DAP_ReadBlock, /* Supported */
|
|
DRXJ_DAP_WriteReg8, /* Not supported */
|
|
DRXJ_DAP_ReadReg8, /* Not supported */
|
|
DRXJ_DAP_ReadModifyWriteReg8, /* Not supported */
|
|
DRXJ_DAP_WriteReg16, /* Supported */
|
|
DRXJ_DAP_ReadReg16, /* Supported */
|
|
DRXJ_DAP_ReadModifyWriteReg16, /* Supported */
|
|
DRXJ_DAP_WriteReg32, /* Supported */
|
|
DRXJ_DAP_ReadReg32, /* Supported */
|
|
DRXJ_DAP_ReadModifyWriteReg32, /* Not supported */
|
|
};
|
|
|
|
/**
|
|
* /var DRXJ_Func_g
|
|
* /brief The driver functions of the drxj
|
|
*/
|
|
DRXDemodFunc_t DRXJFunctions_g =
|
|
{
|
|
DRXJ_TYPE_ID,
|
|
DRXJ_Open,
|
|
DRXJ_Close,
|
|
DRXJ_Ctrl
|
|
};
|
|
|
|
DRXJData_t DRXJData_g =
|
|
{
|
|
FALSE, /* hasLNA : TRUE if LNA (aka PGA) present */
|
|
FALSE, /* hasOOB : TRUE if OOB supported */
|
|
FALSE, /* hasNTSC: TRUE if NTSC supported */
|
|
FALSE, /* hasBTSC: TRUE if BTSC supported */
|
|
FALSE, /* hasSMATX: TRUE if SMA_TX pin is available */
|
|
FALSE, /* hasSMARX: TRUE if SMA_RX pin is available */
|
|
FALSE, /* hasGPIO : TRUE if GPIO pin is available */
|
|
FALSE, /* hasIRQN : TRUE if IRQN pin is available */
|
|
0, /* mfx A1/A2/A... */
|
|
|
|
/* tuner settings */
|
|
FALSE, /* tuner mirrors RF signal */
|
|
/* standard/channel settings */
|
|
DRX_STANDARD_UNKNOWN, /* current standard */
|
|
DRX_CONSTELLATION_AUTO, /* constellation */
|
|
0, /* frequency in KHz */
|
|
DRX_BANDWIDTH_UNKNOWN, /* currBandwidth */
|
|
DRX_MIRROR_NO, /* mirror */
|
|
|
|
/* signal quality information: */
|
|
/* default values taken from the QAM Programming guide */
|
|
/* fecBitsDesired should not be less than 4000000 */
|
|
4000000, /* fecBitsDesired */
|
|
5, /* fecVdPlen */
|
|
4, /* qamVdPrescale */
|
|
0xFFFF, /* qamVDPeriod */
|
|
204*8, /* fecRsPlen annex A */
|
|
1, /* fecRsPrescale */
|
|
FEC_RS_MEASUREMENT_PERIOD,/* fecRsPeriod */
|
|
TRUE, /* resetPktErrAcc */
|
|
0, /* pktErrAccStart */
|
|
|
|
/* HI configuration */
|
|
0, /* HICfgTimingDiv */
|
|
0, /* HICfgBridgeDelay */
|
|
0, /* HICfgWakeUpKey */
|
|
0, /* HICfgCtrl */
|
|
0, /* HICfgTimeout */
|
|
/* UIO configuartion */
|
|
DRX_UIO_MODE_DISABLE, /* uioSmaRxMode */
|
|
DRX_UIO_MODE_DISABLE, /* uioSmaTxMode */
|
|
DRX_UIO_MODE_DISABLE, /* uioASELMode */
|
|
DRX_UIO_MODE_DISABLE, /* uioIRQNMode */
|
|
/* FS setting */
|
|
0UL, /* iqmFsRateOfs */
|
|
FALSE, /* posImage */
|
|
/* RC setting */
|
|
0UL, /* iqmRcRateOfs */
|
|
/* AUD information */
|
|
/* FALSE, * flagSetAUDdone */
|
|
/* FALSE, * detectedRDS */
|
|
/* TRUE, * flagASDRequest */
|
|
/* FALSE, * flagHDevClear */
|
|
/* FALSE, * flagHDevSet */
|
|
/* (u16_t) 0xFFF, * rdsLastCount */
|
|
|
|
/*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
FALSE, * flagAudMcUploaded */
|
|
/*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
|
|
/* ATV configuartion */
|
|
0UL, /* flags cfg changes */
|
|
/* shadow of ATV_TOP_EQU0__A */
|
|
{-5,
|
|
ATV_TOP_EQU0_EQU_C0_FM,
|
|
ATV_TOP_EQU0_EQU_C0_L,
|
|
ATV_TOP_EQU0_EQU_C0_LP,
|
|
ATV_TOP_EQU0_EQU_C0_BG,
|
|
ATV_TOP_EQU0_EQU_C0_DK,
|
|
ATV_TOP_EQU0_EQU_C0_I
|
|
},
|
|
/* shadow of ATV_TOP_EQU1__A */
|
|
{-50,
|
|
ATV_TOP_EQU1_EQU_C1_FM,
|
|
ATV_TOP_EQU1_EQU_C1_L,
|
|
ATV_TOP_EQU1_EQU_C1_LP,
|
|
ATV_TOP_EQU1_EQU_C1_BG,
|
|
ATV_TOP_EQU1_EQU_C1_DK,
|
|
ATV_TOP_EQU1_EQU_C1_I
|
|
},
|
|
/* shadow of ATV_TOP_EQU2__A */
|
|
{210,
|
|
ATV_TOP_EQU2_EQU_C2_FM,
|
|
ATV_TOP_EQU2_EQU_C2_L,
|
|
ATV_TOP_EQU2_EQU_C2_LP,
|
|
ATV_TOP_EQU2_EQU_C2_BG,
|
|
ATV_TOP_EQU2_EQU_C2_DK,
|
|
ATV_TOP_EQU2_EQU_C2_I
|
|
},
|
|
/* shadow of ATV_TOP_EQU3__A */
|
|
{-160,
|
|
ATV_TOP_EQU3_EQU_C3_FM,
|
|
ATV_TOP_EQU3_EQU_C3_L,
|
|
ATV_TOP_EQU3_EQU_C3_LP,
|
|
ATV_TOP_EQU3_EQU_C3_BG,
|
|
ATV_TOP_EQU3_EQU_C3_DK,
|
|
ATV_TOP_EQU3_EQU_C3_I
|
|
},
|
|
FALSE, /* flag: TRUE=bypass */
|
|
ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
|
|
ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
|
|
TRUE, /* flag CVBS ouput enable */
|
|
FALSE, /* flag SIF ouput enable */
|
|
DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
|
|
{ /* qamRfAgcCfg */
|
|
DRX_STANDARD_ITU_B, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel */
|
|
0xFFFF, /* maxOutputLevel */
|
|
0x0000, /* speed */
|
|
0x0000, /* top */
|
|
0x0000 /* c.o.c. */
|
|
},
|
|
{ /* qamIfAgcCfg */
|
|
DRX_STANDARD_ITU_B, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel */
|
|
0xFFFF, /* maxOutputLevel */
|
|
0x0000, /* speed */
|
|
0x0000, /* top (don't care) */
|
|
0x0000 /* c.o.c. (don't care) */
|
|
},
|
|
{ /* vsbRfAgcCfg */
|
|
DRX_STANDARD_8VSB, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel */
|
|
0xFFFF, /* maxOutputLevel */
|
|
0x0000, /* speed */
|
|
0x0000, /* top (don't care) */
|
|
0x0000 /* c.o.c. (don't care) */
|
|
},
|
|
{ /* vsbIfAgcCfg */
|
|
DRX_STANDARD_8VSB, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel */
|
|
0xFFFF, /* maxOutputLevel */
|
|
0x0000, /* speed */
|
|
0x0000, /* top (don't care) */
|
|
0x0000 /* c.o.c. (don't care) */
|
|
},
|
|
0, /* qamPgaCfg */
|
|
0, /* vsbPgaCfg */
|
|
{ /* qamPreSawCfg */
|
|
DRX_STANDARD_ITU_B, /* standard */
|
|
0, /* reference */
|
|
FALSE /* usePreSaw */
|
|
},
|
|
{ /* vsbPreSawCfg */
|
|
DRX_STANDARD_8VSB, /* standard */
|
|
0, /* reference */
|
|
FALSE /* usePreSaw */
|
|
},
|
|
|
|
/* Version information */
|
|
#ifndef _CH_
|
|
{
|
|
"01234567890", /* human readable version microcode */
|
|
"01234567890" /* human readable version device specific code */
|
|
},
|
|
{
|
|
{ /* DRXVersion_t for microcode */
|
|
DRX_MODULE_UNKNOWN,
|
|
(char*)(NULL),
|
|
0,
|
|
0,
|
|
0,
|
|
(char*)(NULL)
|
|
},
|
|
{ /* DRXVersion_t for device specific code */
|
|
DRX_MODULE_UNKNOWN,
|
|
(char*)(NULL),
|
|
0,
|
|
0,
|
|
0,
|
|
(char*)(NULL)
|
|
}
|
|
},
|
|
{
|
|
{ /* DRXVersionList_t for microcode */
|
|
(pDRXVersion_t)(NULL),
|
|
(pDRXVersionList_t)(NULL)
|
|
},
|
|
{ /* DRXVersionList_t for device specific code */
|
|
(pDRXVersion_t)(NULL),
|
|
(pDRXVersionList_t)(NULL)
|
|
}
|
|
},
|
|
#endif
|
|
FALSE, /* smartAntInverted */
|
|
/* Tracking filter setting for OOB */
|
|
{
|
|
12000,
|
|
9300,
|
|
6600,
|
|
5280,
|
|
3700,
|
|
3000,
|
|
2000,
|
|
0
|
|
},
|
|
FALSE, /* oobPowerOn */
|
|
0, /* mpegTsStaticBitrate */
|
|
FALSE, /* disableTEIhandling */
|
|
FALSE, /* bitReverseMpegOutout */
|
|
DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpegOutputClockRate */
|
|
DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpegStartWidth */
|
|
|
|
/* Pre SAW & Agc configuration for ATV */
|
|
{
|
|
DRX_STANDARD_NTSC, /* standard */
|
|
7, /* reference */
|
|
TRUE /* usePreSaw */
|
|
},
|
|
{ /* ATV RF-AGC */
|
|
DRX_STANDARD_NTSC, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel (d.c.) */
|
|
0, /* maxOutputLevel (d.c.) */
|
|
3, /* speed */
|
|
9500, /* top */
|
|
4000 /* cut-off current */
|
|
},
|
|
{ /* ATV IF-AGC */
|
|
DRX_STANDARD_NTSC, /* standard */
|
|
DRX_AGC_CTRL_AUTO, /* ctrlMode */
|
|
0, /* outputLevel */
|
|
0, /* minOutputLevel (d.c.) */
|
|
0, /* maxOutputLevel (d.c.) */
|
|
3, /* speed */
|
|
2400, /* top */
|
|
0 /* c.o.c. (d.c.) */
|
|
},
|
|
140, /* ATV PGA config */
|
|
0, /* currSymbolRate */
|
|
|
|
FALSE, /* pdrSafeMode */
|
|
SIO_PDR_GPIO_CFG__PRE, /* pdrSafeRestoreValGpio */
|
|
SIO_PDR_VSYNC_CFG__PRE, /* pdrSafeRestoreValVSync */
|
|
SIO_PDR_SMA_RX_CFG__PRE, /* pdrSafeRestoreValSmaRx */
|
|
SIO_PDR_SMA_TX_CFG__PRE, /* pdrSafeRestoreValSmaTx */
|
|
|
|
4, /* oobPreSaw */
|
|
DRXJ_OOB_LO_POW_MINUS10DB, /* oobLoPow */
|
|
{
|
|
FALSE /* audData, only first member */
|
|
},
|
|
};
|
|
|
|
|
|
/**
|
|
* \var DRXJDefaultAddr_g
|
|
* \brief Default I2C address and device identifier.
|
|
*/
|
|
I2CDeviceAddr_t DRXJDefaultAddr_g = {
|
|
DRXJ_DEF_I2C_ADDR, /* i2c address */
|
|
DRXJ_DEF_DEMOD_DEV_ID /* device id */
|
|
};
|
|
|
|
/**
|
|
* \var DRXJDefaultCommAttr_g
|
|
* \brief Default common attributes of a drxj demodulator instance.
|
|
*/
|
|
DRXCommonAttr_t DRXJDefaultCommAttr_g = {
|
|
(pu8_t)NULL, /* ucode ptr */
|
|
0, /* ucode size */
|
|
TRUE, /* ucode verify switch */
|
|
{ 0 }, /* version record */
|
|
|
|
44000, /* IF in kHz in case no tuner instance is used */
|
|
(151875-0), /* system clock frequency in kHz */
|
|
0, /* oscillator frequency kHz */
|
|
0, /* oscillator deviation in ppm, signed */
|
|
FALSE, /* If TRUE mirror frequency spectrum */
|
|
{
|
|
/* MPEG output configuration */
|
|
TRUE, /* If TRUE, enable MPEG ouput */
|
|
FALSE, /* If TRUE, insert RS byte */
|
|
TRUE, /* If TRUE, parallel out otherwise serial */
|
|
FALSE, /* If TRUE, invert DATA signals */
|
|
FALSE, /* If TRUE, invert ERR signal */
|
|
FALSE, /* If TRUE, invert STR signals */
|
|
FALSE, /* If TRUE, invert VAL signals */
|
|
FALSE, /* If TRUE, invert CLK signals */
|
|
TRUE, /* If TRUE, static MPEG clockrate will
|
|
be used, otherwise clockrate will
|
|
adapt to the bitrate of the TS */
|
|
19392658UL, /* Maximum bitrate in b/s in case
|
|
static clockrate is selected */
|
|
DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
|
|
},
|
|
/* Initilisations below can be ommited, they require no user input and
|
|
are initialy 0, NULL or FALSE. The compiler will initialize them to these
|
|
values when ommited. */
|
|
FALSE, /* isOpened */
|
|
|
|
/* SCAN */
|
|
NULL, /* no scan params yet */
|
|
0, /* current scan index */
|
|
0, /* next scan frequency */
|
|
FALSE, /* scan ready flag */
|
|
0, /* max channels to scan */
|
|
0, /* nr of channels scanned */
|
|
NULL, /* default scan function */
|
|
NULL, /* default context pointer */
|
|
0, /* millisec to wait for demod lock */
|
|
DRXJ_DEMOD_LOCK, /* desired lock */
|
|
FALSE,
|
|
|
|
/* Power management */
|
|
DRX_POWER_UP,
|
|
|
|
/* Tuner */
|
|
1, /* nr of I2C port to wich tuner is */
|
|
0L, /* minimum RF input frequency, in kHz */
|
|
0L, /* maximum RF input frequency, in kHz */
|
|
FALSE, /* Rf Agc Polarity */
|
|
FALSE, /* If Agc Polarity */
|
|
FALSE, /* tuner slow mode */
|
|
|
|
|
|
{ /* current channel (all 0) */
|
|
0UL /* channel.frequency */
|
|
},
|
|
DRX_STANDARD_UNKNOWN, /* current standard */
|
|
DRX_STANDARD_UNKNOWN, /* previous standard */
|
|
DRX_STANDARD_UNKNOWN, /* diCacheStandard */
|
|
FALSE, /* useBootloader */
|
|
0UL, /* capabilities */
|
|
0 /* mfx */
|
|
|
|
};
|
|
|
|
/**
|
|
* \var DRXJDefaultDemod_g
|
|
* \brief Default drxj demodulator instance.
|
|
*/
|
|
DRXDemodInstance_t DRXJDefaultDemod_g = {
|
|
&DRXJFunctions_g, /* demod functions */
|
|
&DRXJ_DAP, /* data access protocol functions */
|
|
NULL, /* tuner instance */
|
|
&DRXJDefaultAddr_g, /* i2c address & device id */
|
|
&DRXJDefaultCommAttr_g, /* demod common attributes */
|
|
&DRXJData_g /* demod device specific attributes */
|
|
};
|
|
|
|
/**
|
|
* \brief Default audio data structure for DRK demodulator instance.
|
|
*
|
|
* This structure is DRXK specific.
|
|
*
|
|
*/
|
|
DRXAudData_t DRXJDefaultAudData_g =
|
|
{
|
|
FALSE, /* audioIsActive */
|
|
DRX_AUD_STANDARD_AUTO, /* audioStandard */
|
|
|
|
/* i2sdata */
|
|
{
|
|
FALSE, /* outputEnable */
|
|
48000, /* frequency */
|
|
DRX_I2S_MODE_MASTER, /* mode */
|
|
DRX_I2S_WORDLENGTH_32, /* wordLength */
|
|
DRX_I2S_POLARITY_RIGHT, /* polarity */
|
|
DRX_I2S_FORMAT_WS_WITH_DATA /* format */
|
|
},
|
|
/* volume */
|
|
{
|
|
TRUE, /* mute; */
|
|
0, /* volume */
|
|
DRX_AUD_AVC_OFF , /* avcMode */
|
|
0, /* avcRefLevel */
|
|
DRX_AUD_AVC_MAX_GAIN_12DB, /* avcMaxGain */
|
|
DRX_AUD_AVC_MAX_ATTEN_24DB, /* avcMaxAtten */
|
|
0, /* strengthLeft */
|
|
0 /* strengthRight */
|
|
},
|
|
DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON,/* autoSound */
|
|
/* assThresholds */
|
|
{
|
|
440, /* A2 */
|
|
12, /* BTSC */
|
|
700, /* NICAM */
|
|
},
|
|
/* carrier */
|
|
{
|
|
/* a */
|
|
{
|
|
42, /* thres */
|
|
DRX_NO_CARRIER_NOISE, /* opt */
|
|
0, /* shift */
|
|
0 /* dco */
|
|
},
|
|
/* b */
|
|
{
|
|
42, /* thres */
|
|
DRX_NO_CARRIER_MUTE, /* opt */
|
|
0, /* shift */
|
|
0 /* dco */
|
|
},
|
|
|
|
},
|
|
/* mixer */
|
|
{
|
|
DRX_AUD_SRC_STEREO_OR_A, /* sourceI2S */
|
|
DRX_AUD_I2S_MATRIX_STEREO, /* matrixI2S */
|
|
DRX_AUD_FM_MATRIX_SOUND_A /* matrixFm */
|
|
},
|
|
DRX_AUD_DEVIATION_NORMAL, /* deviation */
|
|
DRX_AUD_AVSYNC_OFF, /* avSync */
|
|
|
|
/* prescale */
|
|
{
|
|
DRX_AUD_MAX_FM_DEVIATION, /* fmDeviation */
|
|
DRX_AUD_MAX_NICAM_PRESCALE /* nicamGain */
|
|
},
|
|
DRX_AUD_FM_DEEMPH_75US, /* deemph */
|
|
DRX_BTSC_STEREO, /* btscDetect */
|
|
0, /* rdsDataCounter */
|
|
FALSE /* rdsDataPresent */
|
|
};
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
STRUCTURES
|
|
----------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
u16_t eqMSE;
|
|
u8_t eqMode;
|
|
u8_t eqCtrl;
|
|
u8_t eqStat;
|
|
} DRXJEQStat_t, *pDRXJEQStat_t;
|
|
|
|
/* HI command */
|
|
typedef struct {
|
|
u16_t cmd;
|
|
u16_t param1;
|
|
u16_t param2;
|
|
u16_t param3;
|
|
u16_t param4;
|
|
u16_t param5;
|
|
u16_t param6;
|
|
} DRXJHiCmd_t, *pDRXJHiCmd_t;
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
/*============================================================================*/
|
|
/*=== MICROCODE RELATED STRUCTURES ===========================================*/
|
|
/*============================================================================*/
|
|
|
|
typedef struct {
|
|
u32_t addr;
|
|
u16_t size;
|
|
u16_t flags; /* bit[15..2]=reserved,
|
|
bit[1]= compression on/off
|
|
bit[0]= CRC on/off */
|
|
u16_t CRC;
|
|
} DRXUCodeBlockHdr_t, *pDRXUCodeBlockHdr_t;
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FUNCTIONS
|
|
----------------------------------------------------------------------------*/
|
|
/* Some prototypes */
|
|
static DRXStatus_t
|
|
HICommand(const pI2CDeviceAddr_t devAddr,
|
|
const pDRXJHiCmd_t cmd,
|
|
pu16_t result);
|
|
|
|
static DRXStatus_t
|
|
CtrlLockStatus( pDRXDemodInstance_t demod,
|
|
pDRXLockStatus_t lockStat );
|
|
|
|
static DRXStatus_t
|
|
CtrlPowerMode( pDRXDemodInstance_t demod,
|
|
pDRXPowerMode_t mode );
|
|
|
|
static DRXStatus_t
|
|
PowerDownAud( pDRXDemodInstance_t demod );
|
|
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
PowerUpAud( pDRXDemodInstance_t demod,
|
|
Bool_t setStandard );
|
|
#endif
|
|
|
|
static DRXStatus_t
|
|
AUDCtrlSetStandard ( pDRXDemodInstance_t demod,
|
|
pDRXAudStandard_t standard );
|
|
|
|
static DRXStatus_t
|
|
CtrlSetCfgPreSaw ( pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw );
|
|
|
|
static DRXStatus_t
|
|
CtrlSetCfgAfeGain ( pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain );
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
static DRXStatus_t
|
|
CtrlUCodeUpload( pDRXDemodInstance_t demod,
|
|
pDRXUCodeInfo_t mcInfo,
|
|
DRXUCodeAction_t action,
|
|
Bool_t audioMCUpload );
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== HELPER FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn void Mult32(u32_t a, u32_t b, pu32_t h, pu32_t l)
|
|
* \brief 32bitsx32bits signed multiplication
|
|
* \param a 32 bits multiplicant, typecast from signed to unisgned
|
|
* \param b 32 bits multiplier, typecast from signed to unisgned
|
|
* \param h pointer to high part 64 bits result, typecast from signed to unisgned
|
|
* \param l pointer to low part 64 bits result
|
|
*
|
|
* For the 2n+n addition a + b:
|
|
* if a >= 0, then h += 0 (sign extension = 0)
|
|
* but if a < 0, then h += 2^n-1 ==> h -= 1.
|
|
*
|
|
* Also, if a + b < 2^n, then a + b >= a && a + b >= b
|
|
* but if a + b >= 2^n, then R = a + b - 2^n,
|
|
* and because a < 2^n && b < 2*n ==> R < a && R < b.
|
|
* Therefore, to detect overflow, simply compare the addition result with
|
|
* one of the operands; if the result is smaller, overflow has occurred and
|
|
* h must be incremented.
|
|
*
|
|
* Booth multiplication uses additions and subtractions to reduce the number
|
|
* of iterations. This is done by taking three subsequent bits abc and calculating
|
|
* the following multiplication factor: -2a + b + c. This factor is multiplied
|
|
* by the second operand and added to the result. Next, the first operand is
|
|
* shifted two bits (hence one of the three bits is reused) and the process
|
|
* repeated. The last iteration has only two bits left, but we simply add
|
|
* a zero to the end.
|
|
*
|
|
* Hence: (n=4)
|
|
* 1 * a = 0 * 4a + 1 * a
|
|
* 2 * a = 1 * 4a - 2 * a
|
|
* 3 * a = 1 * 4a - 1 * a
|
|
* -1 * a = 0 * 4a - 1 * a
|
|
* -5 * a = -1 * 4a - 1 * a
|
|
*
|
|
* etc.
|
|
*
|
|
* Note that the function is type size independent. Any unsigned integer type
|
|
* can be substituted for booth_t.
|
|
*
|
|
*/
|
|
|
|
#define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof (u32_t) * 8 - 1))) != 0)
|
|
|
|
static void Mult32(u32_t a, u32_t b, pu32_t h, pu32_t l)
|
|
{
|
|
unsigned int i;
|
|
*h = *l = 0;
|
|
|
|
/* n/2 iterations; shift operand a left two bits after each iteration. */
|
|
/* This automatically appends a zero to the operand for the last iteration. */
|
|
for (i = 0; i < sizeof (a) * 8; i += 2, a = a << 2)
|
|
{
|
|
/* Shift result left two bits */
|
|
*h = (*h << 2) + (*l >> (sizeof (*l) * 8 - 2));
|
|
*l = (*l << 2);
|
|
|
|
/* Take the first three bits of operand a for the Booth conversion: */
|
|
/* 0, 7: do nothing */
|
|
/* 1, 2: add b */
|
|
/* 3 : add 2b */
|
|
/* 4 : subtract 2b */
|
|
/* 5, 6: subtract b */
|
|
switch (a >> (sizeof (a) * 8 - 3))
|
|
{
|
|
case 3:
|
|
*l += b;
|
|
*h = *h - DRX_IS_BOOTH_NEGATIVE (b) + (*l < b);
|
|
case 1:
|
|
case 2:
|
|
*l += b;
|
|
*h = *h - DRX_IS_BOOTH_NEGATIVE (b) + (*l < b);
|
|
break;
|
|
case 4:
|
|
*l -= b;
|
|
*h = *h - !DRX_IS_BOOTH_NEGATIVE (b) + !b + (*l < ((u32_t) (-((s32_t)b))) );
|
|
case 5:
|
|
case 6:
|
|
*l -= b;
|
|
*h = *h - !DRX_IS_BOOTH_NEGATIVE (b) + !b + (*l < ((u32_t) (-((s32_t)b))) );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/*
|
|
* \fn u32_t Frac28(u32_t N, u32_t D)
|
|
* \brief Compute: (1<<28)*N/D
|
|
* \param N 32 bits
|
|
* \param D 32 bits
|
|
* \return (1<<28)*N/D
|
|
* This function is used to avoid floating-point calculations as they may
|
|
* not be present on the target platform.
|
|
|
|
* Frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
|
|
* fraction used for setting the Frequency Shifter registers.
|
|
* N and D can hold numbers up to width: 28-bits.
|
|
* The 4 bits integer part and the 28 bits fractional part are calculated.
|
|
|
|
* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
|
|
|
|
* N: 0...(1<<28)-1 = 268435454
|
|
* D: 0...(1<<28)-1
|
|
* Q: 0...(1<<32)-1
|
|
*/
|
|
static u32_t Frac28(u32_t N, u32_t D)
|
|
{
|
|
int i=0;
|
|
u32_t Q1=0;
|
|
u32_t R0=0;
|
|
|
|
R0 = (N%D)<<4; /* 32-28 == 4 shifts possible at max */
|
|
Q1 = N/D; /* integer part, only the 4 least significant bits
|
|
will be visible in the result */
|
|
|
|
/* division using radix 16, 7 nibbles in the result */
|
|
for (i=0; i<7; i++) {
|
|
Q1 = (Q1 << 4) | R0/D;
|
|
R0 = (R0%D)<<4;
|
|
}
|
|
/* rounding */
|
|
if ((R0>>3) >= D) Q1++;
|
|
|
|
return Q1;
|
|
}
|
|
|
|
/**
|
|
* \fn u32_t Log10Times100( u32_t x)
|
|
* \brief Compute: 100*log10(x)
|
|
* \param x 32 bits
|
|
* \return 100*log10(x)
|
|
*
|
|
* 100*log10(x)
|
|
* = 100*(log2(x)/log2(10)))
|
|
* = (100*(2^15)*log2(x))/((2^15)*log2(10))
|
|
* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
|
|
* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
|
|
* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
|
|
*
|
|
* where y = 2^k and 1<= (x/y) < 2
|
|
*/
|
|
|
|
static u32_t Log10Times100( u32_t x)
|
|
{
|
|
static const u8_t scale=15;
|
|
static const u8_t indexWidth=5;
|
|
/*
|
|
log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
|
|
0 <= n < ((1<<INDEXWIDTH)+1)
|
|
*/
|
|
|
|
static const u32_t log2lut[] = {
|
|
0, /* 0.000000 */
|
|
290941, /* 290941.300628 */
|
|
573196, /* 573196.476418 */
|
|
847269, /* 847269.179851 */
|
|
1113620, /* 1113620.489452 */
|
|
1372674, /* 1372673.576986 */
|
|
1624818, /* 1624817.752104 */
|
|
1870412, /* 1870411.981536 */
|
|
2109788, /* 2109787.962654 */
|
|
2343253, /* 2343252.817465 */
|
|
2571091, /* 2571091.461923 */
|
|
2793569, /* 2793568.696416 */
|
|
3010931, /* 3010931.055901 */
|
|
3223408, /* 3223408.452106 */
|
|
3431216, /* 3431215.635215 */
|
|
3634553, /* 3634553.498355 */
|
|
3833610, /* 3833610.244726 */
|
|
4028562, /* 4028562.434393 */
|
|
4219576, /* 4219575.925308 */
|
|
4406807, /* 4406806.721144 */
|
|
4590402, /* 4590401.736809 */
|
|
4770499, /* 4770499.491025 */
|
|
4947231, /* 4947230.734179 */
|
|
5120719, /* 5120719.018555 */
|
|
5291081, /* 5291081.217197 */
|
|
5458428, /* 5458427.996830 */
|
|
5622864, /* 5622864.249668 */
|
|
5784489, /* 5784489.488298 */
|
|
5943398, /* 5943398.207380 */
|
|
6099680, /* 6099680.215452 */
|
|
6253421, /* 6253420.939751 */
|
|
6404702, /* 6404701.706649 */
|
|
6553600, /* 6553600.000000 */
|
|
};
|
|
|
|
|
|
u8_t i = 0;
|
|
u32_t y = 0;
|
|
u32_t d = 0;
|
|
u32_t k = 0;
|
|
u32_t r = 0;
|
|
|
|
if (x==0) return (0);
|
|
|
|
/* Scale x (normalize) */
|
|
/* computing y in log(x/y) = log(x) - log(y) */
|
|
if ( (x & (((u32_t)(-1))<<(scale+1)) ) == 0 )
|
|
{
|
|
for (k = scale; k>0 ; k--)
|
|
{
|
|
if (x & (((u32_t)1)<<scale)) break;
|
|
x <<= 1;
|
|
}
|
|
} else {
|
|
for (k = scale; k<31 ; k++)
|
|
{
|
|
if ((x & (((u32_t)(-1))<<(scale+1)))==0) break;
|
|
x >>= 1;
|
|
}
|
|
}
|
|
/*
|
|
Now x has binary point between bit[scale] and bit[scale-1]
|
|
and 1.0 <= x < 2.0 */
|
|
|
|
/* correction for divison: log(x) = log(x/y)+log(y) */
|
|
y = k * ( ( ((u32_t)1) << scale ) * 200 );
|
|
|
|
/* remove integer part */
|
|
x &= ((((u32_t)1) << scale)-1);
|
|
/* get index */
|
|
i = (u8_t) (x >> (scale -indexWidth));
|
|
/* compute delta (x-a) */
|
|
d = x & ((((u32_t)1) << (scale-indexWidth))-1);
|
|
/* compute log, multiplication ( d* (.. )) must be within range ! */
|
|
y += log2lut[i] + (( d*( log2lut[i+1]-log2lut[i] ))>>(scale-indexWidth));
|
|
/* Conver to log10() */
|
|
y /= 108853; /* (log2(10) << scale) */
|
|
r = (y>>1);
|
|
/* rounding */
|
|
if (y&((u32_t)1)) r++;
|
|
|
|
return (r);
|
|
|
|
}
|
|
|
|
/**
|
|
* \fn u32_t FracTimes1e6( u16_t N, u32_t D)
|
|
* \brief Compute: (N/D) * 1000000.
|
|
* \param N nominator 16-bits.
|
|
* \param D denominator 32-bits.
|
|
* \return u32_t
|
|
* \retval ((N/D) * 1000000), 32 bits
|
|
*
|
|
* No check on D=0!
|
|
*/
|
|
static u32_t FracTimes1e6( u32_t N, u32_t D)
|
|
{
|
|
u32_t remainder = 0;
|
|
u32_t frac = 0;
|
|
|
|
/*
|
|
frac = (N * 1000000) / D
|
|
To let it fit in a 32 bits computation:
|
|
frac = (N * (1000000 >> 4)) / (D >> 4)
|
|
This would result in a problem in case D < 16 (div by 0).
|
|
So we do it more elaborate as shown below.
|
|
*/
|
|
frac = ( ((u32_t)N) * (1000000 >> 4) ) / D ;
|
|
frac <<= 4 ;
|
|
remainder = ( ((u32_t)N) * (1000000 >> 4) ) % D ;
|
|
remainder <<= 4;
|
|
frac += remainder / D;
|
|
remainder = remainder % D ;
|
|
if( (remainder * 2) > D )
|
|
{
|
|
frac++;
|
|
}
|
|
|
|
return ( frac );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \brief Compute: 100 * 10^( GdB / 200 ).
|
|
* \param u32_t GdB Gain in 0.1dB
|
|
* \return u32_t Gainfactor in 0.01 resolution
|
|
*
|
|
*/
|
|
static u32_t dB2LinTimes100( u32_t GdB )
|
|
{
|
|
u32_t result = 0;
|
|
u32_t nr6dBSteps = 0;
|
|
u32_t remainder = 0;
|
|
u32_t remainderFac = 0;
|
|
|
|
/* start with factors 2 (6.02dB) */
|
|
nr6dBSteps = GdB * 1000UL / 60206UL;
|
|
if ( nr6dBSteps > 17 )
|
|
{
|
|
/* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
|
|
return MAX_U32;
|
|
}
|
|
result = (1<<nr6dBSteps);
|
|
|
|
/* calculate remaining factor,
|
|
poly approximation of 10^(GdB/200):
|
|
|
|
y = 1E-04x2 + 0.0106x + 1.0026
|
|
|
|
max deviation < 0.005 for range x = [0 ... 60]
|
|
*/
|
|
remainder = ( ( GdB * 1000UL ) % 60206UL ) / 1000UL;
|
|
/* using 1e-4 for poly calculation */
|
|
remainderFac = 1 * remainder * remainder;
|
|
remainderFac += 106 * remainder;
|
|
remainderFac += 10026;
|
|
|
|
/* multiply by remaining factor */
|
|
result *= remainderFac;
|
|
|
|
/* conversion from 1e-4 to 1e-2 */
|
|
return ( (result + 50 ) / 100);
|
|
}
|
|
|
|
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
#define FRAC_FLOOR 0
|
|
#define FRAC_CEIL 1
|
|
#define FRAC_ROUND 2
|
|
/**
|
|
* \fn u32_t Frac( u32_t N, u32_t D, u16_t RC )
|
|
* \brief Compute: N/D.
|
|
* \param N nominator 32-bits.
|
|
* \param D denominator 32-bits.
|
|
* \param RC-result correction: 0-floor; 1-ceil; 2-round
|
|
* \return u32_t
|
|
* \retval N/D, 32 bits
|
|
*
|
|
* If D=0 returns 0
|
|
*/
|
|
static u32_t Frac( u32_t N, u32_t D, u16_t RC )
|
|
{
|
|
u32_t remainder = 0;
|
|
u32_t frac = 0;
|
|
u16_t bitCnt = 32;
|
|
|
|
if ( D == 0 )
|
|
{
|
|
frac = 0;
|
|
remainder = 0;
|
|
|
|
return ( frac );
|
|
}
|
|
|
|
if ( D > N )
|
|
{
|
|
frac = 0;
|
|
remainder = N;
|
|
}
|
|
else
|
|
{
|
|
remainder = 0;
|
|
frac = N;
|
|
while ( bitCnt-- > 0 )
|
|
{
|
|
remainder <<= 1;
|
|
remainder |= ( ( frac & 0x80000000 ) >> 31 );
|
|
frac <<= 1;
|
|
if ( remainder < D )
|
|
{
|
|
frac &= 0xFFFFFFFE;
|
|
}
|
|
else
|
|
{
|
|
remainder -= D;
|
|
frac |= 0x1;
|
|
}
|
|
}
|
|
|
|
/* result correction if needed */
|
|
if ( ( RC == FRAC_CEIL ) && ( remainder != 0 ) )
|
|
{
|
|
/* ceil the result */
|
|
/*(remainder is not zero -> value behind decimal point exists) */
|
|
frac++;
|
|
}
|
|
if ( ( RC == FRAC_ROUND ) && ( remainder >= D>>1 ) )
|
|
{
|
|
/* remainder is bigger from D/2 -> round the result */
|
|
frac++;
|
|
}
|
|
}
|
|
|
|
return ( frac );
|
|
}
|
|
#endif
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn u16_t UCodeRead16( pu8_t addr)
|
|
* \brief Read a 16 bits word, expect big endian data.
|
|
* \return u16_t The data read.
|
|
*/
|
|
static u16_t
|
|
UCodeRead16( pu8_t addr)
|
|
{
|
|
/* Works fo any host processor */
|
|
|
|
u16_t word=0;
|
|
|
|
word = ((u16_t)addr[0]);
|
|
word <<= 8;
|
|
word |=((u16_t)addr[1]);
|
|
|
|
return ( word );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn u32_t UCodeRead32( pu8_t addr)
|
|
* \brief Read a 32 bits word, expect big endian data.
|
|
* \return u32_t The data read.
|
|
*/
|
|
static u32_t
|
|
UCodeRead32( pu8_t addr)
|
|
{
|
|
/* Works fo any host processor */
|
|
|
|
u32_t word=0;
|
|
|
|
word = ((u16_t)addr[0]);
|
|
word <<= 8;
|
|
word |= ((u16_t)addr[1]);
|
|
word <<= 8;
|
|
word |= ((u16_t)addr[2]);
|
|
word <<= 8;
|
|
word |= ((u16_t)addr[3]);
|
|
|
|
return ( word );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn u16_t UCodeComputeCRC (pu8_t blockData, u16_t nrWords)
|
|
* \brief Compute CRC of block of microcode data.
|
|
* \param blockData Pointer to microcode data.
|
|
* \param nrWords Size of microcode block (number of 16 bits words).
|
|
* \return u16_t The computed CRC residu.
|
|
*/
|
|
static u16_t
|
|
UCodeComputeCRC (pu8_t blockData, u16_t nrWords)
|
|
{
|
|
u16_t i = 0;
|
|
u16_t j = 0;
|
|
u32_t CRCWord=0;
|
|
u32_t carry=0;
|
|
|
|
while (i < nrWords) {
|
|
CRCWord |= (u32_t) UCodeRead16(blockData);
|
|
for (j = 0; j < 16; j++)
|
|
{
|
|
CRCWord <<= 1;
|
|
if (carry != 0)
|
|
CRCWord ^= 0x80050000UL;
|
|
carry = CRCWord & 0x80000000UL;
|
|
}
|
|
i++;
|
|
blockData+=(sizeof(u16_t));
|
|
}
|
|
return ((u16_t) (CRCWord >> 16));
|
|
}
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
/**
|
|
* \brief Values for NICAM prescaler gain. Computed from dB to integer
|
|
* and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
|
|
*
|
|
*/
|
|
static const u16_t NicamPrescTableVal[43] = { 1,1,1,1,2,2,2,2,3,3,3,4,4,
|
|
5,5,6,6,7,8,9,10,11,13,14,16,
|
|
18,20,23,25,28,32,36,40,45,
|
|
51,57,64,71,80,90,101,113,127
|
|
};
|
|
|
|
/*============================================================================*/
|
|
/*== END HELPER FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== DRXJ DAP FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/*
|
|
This layer takes care of some device specific register access protocols:
|
|
-conversion to short address format
|
|
-access to audio block
|
|
This layer is placed between the drx_dap_fasi and the rest of the drxj
|
|
specific implementation. This layer can use address map knowledge whereas
|
|
dap_fasi may not use memory map knowledge.
|
|
|
|
* For audio currently only 16 bits read and write register access is
|
|
supported. More is not needed. RMW and 32 or 8 bit access on audio
|
|
registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
|
|
single/multi master) will be ignored.
|
|
|
|
|
|
TODO: check ignoring single/multimaster is ok for AUD access ?
|
|
*/
|
|
|
|
#define DRXJ_ISAUDWRITE( addr ) (((((addr)>>16)&1)==1)?TRUE:FALSE)
|
|
#define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn Bool_t IsHandledByAudTrIf( DRXaddr_t addr )
|
|
* \brief Check if this address is handled by the audio token ring interface.
|
|
* \param addr
|
|
* \return Bool_t
|
|
* \retval TRUE Yes, handled by audio token ring interface
|
|
* \retval FALSE No, not handled by audio token ring interface
|
|
*
|
|
*/
|
|
static
|
|
Bool_t IsHandledByAudTrIf( DRXaddr_t addr )
|
|
{
|
|
Bool_t retval = FALSE;
|
|
|
|
if ( (DRXDAP_FASI_ADDR2BLOCK( addr ) == 4) &&
|
|
( DRXDAP_FASI_ADDR2BANK( addr) > 1 ) &&
|
|
( DRXDAP_FASI_ADDR2BANK( addr) < 6 ) )
|
|
{
|
|
retval=TRUE;
|
|
}
|
|
|
|
return (retval);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize,
|
|
pu8_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.readBlockFunc( devAddr,
|
|
addr,
|
|
datasize,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u8_t wdata,
|
|
pu8_t rdata)
|
|
{
|
|
return drxDapFASIFunct_g.readModifyWriteReg8Func( devAddr,
|
|
waddr,
|
|
raddr,
|
|
wdata,
|
|
rdata);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_RMWriteReg16Short
|
|
* \brief Read modify write 16 bits audio register using short format only.
|
|
* \param devAddr
|
|
* \param waddr Address to write to
|
|
* \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
|
|
* \param wdata Data to write
|
|
* \param rdata Buffer for data to read
|
|
* \return DRXStatus_t
|
|
* \retval DRX_STS_OK Succes
|
|
* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
|
|
*
|
|
* 16 bits register read modify write access using short addressing format only.
|
|
* Requires knowledge of the registermap, thus device dependent.
|
|
* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
|
|
*
|
|
*/
|
|
|
|
/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
|
|
See comments DRXJ_DAP_ReadModifyWriteReg16 */
|
|
#if ( DRXDAPFASI_LONG_ADDR_ALLOWED == 0 )
|
|
static DRXStatus_t DRXJ_DAP_RMWriteReg16Short (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u16_t wdata,
|
|
pu16_t rdata)
|
|
{
|
|
DRXStatus_t rc;
|
|
|
|
if (rdata == NULL)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* Set RMW flag */
|
|
rc = drxDapFASIFunct_g.writeReg16Func (devAddr,
|
|
SIO_HI_RA_RAM_S0_FLG_ACC__A,
|
|
SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
|
|
0x0000);
|
|
if (rc == DRX_STS_OK)
|
|
{
|
|
/* Write new data: triggers RMW */
|
|
rc = drxDapFASIFunct_g.writeReg16Func (devAddr, waddr, wdata, 0x0000 );
|
|
}
|
|
if (rc == DRX_STS_OK)
|
|
{
|
|
/* Read old data */
|
|
rc = drxDapFASIFunct_g.readReg16Func (devAddr, raddr, rdata, 0x0000 );
|
|
}
|
|
if (rc == DRX_STS_OK)
|
|
{
|
|
/* Reset RMW flag */
|
|
rc = drxDapFASIFunct_g.writeReg16Func (devAddr,
|
|
SIO_HI_RA_RAM_S0_FLG_ACC__A,
|
|
0,
|
|
0x0000);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
#endif
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u16_t wdata,
|
|
pu16_t rdata)
|
|
{
|
|
/* TODO: correct short/long addressing format decision,
|
|
now long format has higher prio then short because short also
|
|
needs virt bnks (not impl yet) for certain audio registers */
|
|
#if ( DRXDAPFASI_LONG_ADDR_ALLOWED==1 )
|
|
return drxDapFASIFunct_g.readModifyWriteReg16Func( devAddr,
|
|
waddr,
|
|
raddr,
|
|
wdata,
|
|
rdata);
|
|
#else
|
|
return DRXJ_DAP_RMWriteReg16Short( devAddr,
|
|
waddr,
|
|
raddr,
|
|
wdata,
|
|
rdata);
|
|
#endif
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadModifyWriteReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t waddr,
|
|
DRXaddr_t raddr,
|
|
u32_t wdata,
|
|
pu32_t rdata)
|
|
{
|
|
return drxDapFASIFunct_g.readModifyWriteReg32Func( devAddr,
|
|
waddr,
|
|
raddr,
|
|
wdata,
|
|
rdata);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu8_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.readReg8Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_ReadAudReg16
|
|
* \brief Read 16 bits audio register
|
|
* \param devAddr
|
|
* \param addr
|
|
* \param data
|
|
* \return DRXStatus_t
|
|
* \retval DRX_STS_OK Succes
|
|
* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
|
|
*
|
|
* 16 bits register read access via audio token ring interface.
|
|
*
|
|
*/
|
|
static DRXStatus_t DRXJ_DAP_ReadAudReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu16_t data)
|
|
{
|
|
u32_t startTimer = 0;
|
|
u32_t currentTimer = 0;
|
|
u32_t deltaTimer = 0;
|
|
u16_t trStatus = 0;
|
|
DRXStatus_t stat = DRX_STS_ERROR;
|
|
|
|
/* No read possible for bank 3, return with error */
|
|
if ( DRXDAP_FASI_ADDR2BANK(addr) == 3 )
|
|
{
|
|
stat=DRX_STS_INVALID_ARG;
|
|
} else {
|
|
const DRXaddr_t writeBit = ((DRXaddr_t)1)<<16;
|
|
|
|
/* Force reset write bit */
|
|
addr &= (~writeBit);
|
|
|
|
/* Set up read */
|
|
startTimer = DRXBSP_HST_Clock();
|
|
do {
|
|
/* RMW to aud TR IF until request is granted or timeout */
|
|
stat = DRXJ_DAP_ReadModifyWriteReg16( devAddr,
|
|
addr,
|
|
SIO_HI_RA_RAM_S0_RMWBUF__A,
|
|
0x0000,
|
|
&trStatus);
|
|
|
|
if ( stat != DRX_STS_OK )
|
|
{
|
|
break;
|
|
};
|
|
|
|
currentTimer = DRXBSP_HST_Clock();
|
|
deltaTimer = currentTimer - startTimer;
|
|
if ( deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT )
|
|
{
|
|
stat = DRX_STS_ERROR;
|
|
break;
|
|
};
|
|
|
|
} while ( ( ( trStatus & AUD_TOP_TR_CTR_FIFO_LOCK__M ) ==
|
|
AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED ) ||
|
|
( ( trStatus & AUD_TOP_TR_CTR_FIFO_FULL__M ) ==
|
|
AUD_TOP_TR_CTR_FIFO_FULL_FULL ) );
|
|
} /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
|
|
|
|
/* Wait for read ready status or timeout */
|
|
if ( stat == DRX_STS_OK )
|
|
{
|
|
startTimer = DRXBSP_HST_Clock();
|
|
|
|
while ( ( trStatus & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
|
|
AUD_TOP_TR_CTR_FIFO_RD_RDY_READY)
|
|
{
|
|
stat = DRXJ_DAP_ReadReg16( devAddr,
|
|
AUD_TOP_TR_CTR__A,
|
|
&trStatus,
|
|
0x0000);
|
|
if ( stat != DRX_STS_OK )
|
|
{
|
|
break;
|
|
};
|
|
|
|
currentTimer = DRXBSP_HST_Clock();
|
|
deltaTimer = currentTimer - startTimer;
|
|
if ( deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT )
|
|
{
|
|
stat = DRX_STS_ERROR;
|
|
break;
|
|
};
|
|
} /* while ( ... ) */
|
|
} /* if { stat == DRX_STS_OK ) */
|
|
|
|
/* Read value */
|
|
if ( stat == DRX_STS_OK )
|
|
{
|
|
stat = DRXJ_DAP_ReadModifyWriteReg16( devAddr,
|
|
AUD_TOP_TR_RD_REG__A,
|
|
SIO_HI_RA_RAM_S0_RMWBUF__A,
|
|
0x0000,
|
|
data);
|
|
} /* if { stat == DRX_STS_OK ) */
|
|
|
|
return stat;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu16_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
DRXStatus_t stat = DRX_STS_ERROR;
|
|
|
|
/* Check param */
|
|
if ( ( devAddr == NULL ) || ( data == NULL ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
if ( IsHandledByAudTrIf(addr) )
|
|
{
|
|
stat = DRXJ_DAP_ReadAudReg16 (devAddr,
|
|
addr,
|
|
data);
|
|
} else {
|
|
stat = drxDapFASIFunct_g.readReg16Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_ReadReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu32_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.readReg32Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize,
|
|
pu8_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.writeBlockFunc( devAddr,
|
|
addr,
|
|
datasize,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg8 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u8_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.writeReg8Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_WriteAudReg16
|
|
* \brief Write 16 bits audio register
|
|
* \param devAddr
|
|
* \param addr
|
|
* \param data
|
|
* \return DRXStatus_t
|
|
* \retval DRX_STS_OK Succes
|
|
* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
|
|
*
|
|
* 16 bits register write access via audio token ring interface.
|
|
*
|
|
*/
|
|
static DRXStatus_t DRXJ_DAP_WriteAudReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t data)
|
|
{
|
|
DRXStatus_t stat = DRX_STS_ERROR;
|
|
|
|
/* No write possible for bank 2, return with error */
|
|
if ( DRXDAP_FASI_ADDR2BANK(addr) == 2 )
|
|
{
|
|
stat=DRX_STS_INVALID_ARG;
|
|
} else {
|
|
u32_t startTimer = 0;
|
|
u32_t currentTimer = 0;
|
|
u32_t deltaTimer = 0;
|
|
u16_t trStatus = 0;
|
|
const DRXaddr_t writeBit = ((DRXaddr_t)1)<<16;
|
|
|
|
/* Force write bit */
|
|
addr |= writeBit;
|
|
startTimer = DRXBSP_HST_Clock();
|
|
do {
|
|
/* RMW to aud TR IF until request is granted or timeout */
|
|
stat = DRXJ_DAP_ReadModifyWriteReg16( devAddr,
|
|
addr,
|
|
SIO_HI_RA_RAM_S0_RMWBUF__A,
|
|
data,
|
|
&trStatus);
|
|
if ( stat != DRX_STS_OK )
|
|
{
|
|
break;
|
|
};
|
|
|
|
currentTimer = DRXBSP_HST_Clock();
|
|
deltaTimer = currentTimer - startTimer;
|
|
if ( deltaTimer > DRXJ_DAP_AUDTRIF_TIMEOUT )
|
|
{
|
|
stat = DRX_STS_ERROR;
|
|
break;
|
|
};
|
|
|
|
} while ( ( ( trStatus & AUD_TOP_TR_CTR_FIFO_LOCK__M ) ==
|
|
AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED ) ||
|
|
( ( trStatus & AUD_TOP_TR_CTR_FIFO_FULL__M ) ==
|
|
AUD_TOP_TR_CTR_FIFO_FULL_FULL ) );
|
|
|
|
} /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
|
|
|
|
return stat;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
DRXStatus_t stat=DRX_STS_ERROR;
|
|
|
|
/* Check param */
|
|
if ( devAddr == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
|
|
if ( IsHandledByAudTrIf(addr) )
|
|
{
|
|
stat = DRXJ_DAP_WriteAudReg16 (devAddr,
|
|
addr,
|
|
data);
|
|
} else {
|
|
stat = drxDapFASIFunct_g.writeReg16Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
static DRXStatus_t DRXJ_DAP_WriteReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u32_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
return drxDapFASIFunct_g.writeReg32Func( devAddr,
|
|
addr,
|
|
data,
|
|
flags);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/* Free data ram in SIO HI */
|
|
#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
|
|
#define SIO_HI_RA_RAM_USR_END__A 0x420060
|
|
|
|
#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
|
|
#define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
|
|
#define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
|
|
#define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_AtomicReadWriteBlock()
|
|
* \brief Basic access routine for atomic read or write access
|
|
* \param devAddr pointer to i2c dev address
|
|
* \param addr destination/source address
|
|
* \param datasize size of data buffer in bytes
|
|
* \param data pointer to data buffer
|
|
* \return DRXStatus_t
|
|
* \retval DRX_STS_OK Succes
|
|
* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
|
|
*
|
|
*/
|
|
static
|
|
DRXStatus_t DRXJ_DAP_AtomicReadWriteBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize,
|
|
pu8_t data,
|
|
Bool_t readFlag)
|
|
{
|
|
DRXJHiCmd_t hiCmd;
|
|
|
|
u16_t word;
|
|
u16_t dummy=0;
|
|
u16_t i=0;
|
|
|
|
/* Parameter check */
|
|
if ( ( data == NULL ) ||
|
|
( devAddr == NULL ) ||
|
|
( (datasize%2)!= 0 ) ||
|
|
( (datasize/2) > 8 )
|
|
)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* Set up HI parameters to read or write n bytes */
|
|
hiCmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
|
|
hiCmd.param1 =
|
|
(u16_t)(( DRXDAP_FASI_ADDR2BLOCK( DRXJ_HI_ATOMIC_BUF_START ) << 6 ) +
|
|
DRXDAP_FASI_ADDR2BANK( DRXJ_HI_ATOMIC_BUF_START ) );
|
|
hiCmd.param2 = (u16_t)DRXDAP_FASI_ADDR2OFFSET( DRXJ_HI_ATOMIC_BUF_START );
|
|
hiCmd.param3 = (u16_t)((datasize/2) - 1);
|
|
if ( readFlag == FALSE )
|
|
{
|
|
hiCmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
|
|
} else {
|
|
hiCmd.param3 |= DRXJ_HI_ATOMIC_READ;
|
|
}
|
|
hiCmd.param4 = (u16_t) ( ( DRXDAP_FASI_ADDR2BLOCK(addr) << 6 ) +
|
|
DRXDAP_FASI_ADDR2BANK(addr) );
|
|
hiCmd.param5 = (u16_t)DRXDAP_FASI_ADDR2OFFSET(addr);
|
|
|
|
if ( readFlag == FALSE )
|
|
{
|
|
/* write data to buffer */
|
|
for (i = 0; i < (datasize/2); i++)
|
|
{
|
|
|
|
|
|
word = ((u16_t)data[2*i]);
|
|
word += (((u16_t)data[(2*i)+1])<<8);
|
|
DRXJ_DAP_WriteReg16 (devAddr, (DRXJ_HI_ATOMIC_BUF_START + i), word, 0);
|
|
}
|
|
}
|
|
|
|
CHK_ERROR( HICommand( devAddr, &hiCmd, &dummy) );
|
|
|
|
if ( readFlag == TRUE )
|
|
{
|
|
/* read data from buffer */
|
|
for (i = 0; i < (datasize/2); i++)
|
|
{
|
|
DRXJ_DAP_ReadReg16 (devAddr, (DRXJ_HI_ATOMIC_BUF_START + i), &word, 0);
|
|
data[2*i] = (u8_t) (word & 0xFF);
|
|
data[(2*i) + 1] = (u8_t) (word >> 8 );
|
|
}
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_AtomicReadReg32()
|
|
* \brief Atomic read of 32 bits words
|
|
*/
|
|
static
|
|
DRXStatus_t DRXJ_DAP_AtomicReadReg32 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu32_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
u8_t buf[sizeof (*data)];
|
|
DRXStatus_t rc = DRX_STS_ERROR;
|
|
u32_t word = 0;
|
|
|
|
if (!data)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
rc = DRXJ_DAP_AtomicReadWriteBlock ( devAddr, addr,
|
|
sizeof (*data), buf, TRUE);
|
|
|
|
word = (u32_t)buf[3];
|
|
word <<= 8;
|
|
word |= (u32_t)buf[2];
|
|
word <<= 8;
|
|
word |= (u32_t)buf[1];
|
|
word <<= 8;
|
|
word |= (u32_t)buf[0];
|
|
|
|
*data = word;
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
|
|
/*============================================================================*/
|
|
/*== END DRXJ DAP FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== HOST INTERFACE FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t HICfgCommand()
|
|
* \brief Configure HI with settings stored in the demod structure.
|
|
* \param demod Demodulator.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine was created because to much orthogonal settings have
|
|
* been put into one HI API function (configure). Especially the I2C bridge
|
|
* enable/disable should not need re-configuration of the HI.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
HICfgCommand(const pDRXDemodInstance_t demod)
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
DRXJHiCmd_t hiCmd;
|
|
u16_t result=0;
|
|
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
|
|
hiCmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
|
|
hiCmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
|
|
hiCmd.param2 = extAttr -> HICfgTimingDiv;
|
|
hiCmd.param3 = extAttr -> HICfgBridgeDelay;
|
|
hiCmd.param4 = extAttr -> HICfgWakeUpKey;
|
|
hiCmd.param5 = extAttr -> HICfgCtrl;
|
|
hiCmd.param6 = extAttr -> HICfgTransmit;
|
|
|
|
CHK_ERROR( HICommand( demod -> myI2CDevAddr, &hiCmd, &result) );
|
|
|
|
/* Reset power down flag (set one call only) */
|
|
extAttr -> HICfgCtrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t HICommand()
|
|
* \brief Configure HI with settings stored in the demod structure.
|
|
* \param devAddr I2C address.
|
|
* \param cmd HI command.
|
|
* \param result HI command result.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Sends command to HI
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
HICommand(const pI2CDeviceAddr_t devAddr,
|
|
const pDRXJHiCmd_t cmd,
|
|
pu16_t result)
|
|
{
|
|
u16_t waitCmd=0;
|
|
u16_t nrRetries = 0;
|
|
Bool_t powerdown_cmd = FALSE;
|
|
|
|
|
|
/* Write parameters */
|
|
switch ( cmd->cmd ) {
|
|
|
|
case SIO_HI_RA_RAM_CMD_CONFIG:
|
|
case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6);
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5);
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4);
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3);
|
|
/* fallthrough */
|
|
case SIO_HI_RA_RAM_CMD_BRDCTRL:
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2);
|
|
WR16(devAddr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1);
|
|
/* fallthrough */
|
|
case SIO_HI_RA_RAM_CMD_NULL:
|
|
/* No parameters */
|
|
break;
|
|
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
break;
|
|
}
|
|
|
|
/* Write command */
|
|
WR16(devAddr, SIO_HI_RA_RAM_CMD__A, cmd->cmd);
|
|
|
|
if ( (cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET )
|
|
{
|
|
/* Allow for HI to reset */
|
|
DRXBSP_HST_Sleep(1);
|
|
}
|
|
|
|
/* Detect power down to ommit reading result */
|
|
powerdown_cmd = (Bool_t)( ( cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG ) &&
|
|
( ((cmd->param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
|
|
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ ) );
|
|
if ( powerdown_cmd == FALSE )
|
|
{
|
|
/* Wait until command rdy */
|
|
do
|
|
{
|
|
nrRetries++;
|
|
if ( nrRetries > DRXJ_MAX_RETRIES )
|
|
{
|
|
goto rw_error;
|
|
};
|
|
|
|
RR16(devAddr, SIO_HI_RA_RAM_CMD__A, &waitCmd);
|
|
} while ( waitCmd != 0 );
|
|
|
|
/* Read result */
|
|
RR16(devAddr, SIO_HI_RA_RAM_RES__A, result);
|
|
|
|
} /* if ( powerdown_cmd == TRUE ) */
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t InitHI( const pDRXDemodInstance_t demod )
|
|
* \brief Initialise and configurate HI.
|
|
* \param demod pointer to demod data.
|
|
* \return DRXStatus_t Return status.
|
|
* \retval DRX_STS_OK Success.
|
|
* \retval DRX_STS_ERROR Failure.
|
|
*
|
|
* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
|
|
* Need to store configuration in driver because of the way I2C
|
|
* bridging is controlled.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
InitHI( const pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXJData_t extAttr =(pDRXJData_t)(NULL);
|
|
pDRXCommonAttr_t commonAttr =(pDRXCommonAttr_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr =(pI2CDeviceAddr_t)(NULL);
|
|
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* PATCH for bug 5003, HI ucode v3.1.0 */
|
|
WR16( devAddr, 0x4301D7, 0x801 );
|
|
|
|
/* Timing div, 250ns/Psys */
|
|
/* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
|
|
extAttr -> HICfgTimingDiv =
|
|
(u16_t)((commonAttr->sysClockFreq/1000)* HI_I2C_DELAY)/1000 ;
|
|
/* Clipping */
|
|
if ( (extAttr -> HICfgTimingDiv) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M )
|
|
{
|
|
extAttr -> HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
|
|
}
|
|
/* Bridge delay, uses oscilator clock */
|
|
/* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
|
|
/* SDA brdige delay */
|
|
extAttr -> HICfgBridgeDelay =
|
|
(u16_t)((commonAttr->oscClockFreq/1000)* HI_I2C_BRIDGE_DELAY)/1000 ;
|
|
/* Clipping */
|
|
if ( (extAttr -> HICfgBridgeDelay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M )
|
|
{
|
|
extAttr -> HICfgBridgeDelay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
|
|
}
|
|
/* SCL bridge delay, same as SDA for now */
|
|
extAttr -> HICfgBridgeDelay += ((extAttr -> HICfgBridgeDelay)<<
|
|
SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
|
|
/* Wakeup key, setting the read flag (as suggest in the documentation) does
|
|
not always result into a working solution (barebones worked VI2C failed).
|
|
Not setting the bit works in all cases . */
|
|
extAttr -> HICfgWakeUpKey = DRXJ_WAKE_UP_KEY;
|
|
/* port/bridge/power down ctrl */
|
|
extAttr -> HICfgCtrl = ( SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE );
|
|
/* transit mode time out delay and watch dog divider */
|
|
extAttr ->HICfgTransmit = SIO_HI_RA_RAM_PAR_6__PRE;
|
|
|
|
CHK_ERROR( HICfgCommand( demod ) );
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/*== END HOST INTERFACE FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== AUXILIARY FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetDeviceCapabilities()
|
|
* \brief Get and store device capabilities.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
* \return DRX_STS_OK Success
|
|
* \retval DRX_STS_ERROR Failure
|
|
*
|
|
* Depending on pulldowns on MDx pins the following internals are set:
|
|
* * commonAttr->oscClockFreq
|
|
* * extAttr->hasLNA
|
|
* * extAttr->hasNTSC
|
|
* * extAttr->hasBTSC
|
|
* * extAttr->hasOOB
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetDeviceCapabilities( pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)(NULL);
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
u16_t sioPdrOhwCfg = 0;
|
|
u32_t sioTopJtagidLo = 0;
|
|
u16_t bid = 0;
|
|
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A , SIO_TOP_COMM_KEY_KEY);
|
|
RR16 ( devAddr, SIO_PDR_OHW_CFG__A , &sioPdrOhwCfg);
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A , SIO_TOP_COMM_KEY__PRE);
|
|
|
|
switch ( (sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M ) )
|
|
{
|
|
case 0:
|
|
/* ignore (bypass ?)*/
|
|
break;
|
|
case 1:
|
|
/* 27 MHz */
|
|
commonAttr->oscClockFreq = 27000;
|
|
break;
|
|
case 2:
|
|
/* 20.25 MHz */
|
|
commonAttr->oscClockFreq = 20250;
|
|
break;
|
|
case 3:
|
|
/* 4 MHz */
|
|
commonAttr->oscClockFreq = 4000;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*
|
|
Determine device capabilities
|
|
Based on pinning v47
|
|
*/
|
|
RR32( devAddr, SIO_TOP_JTAGID_LO__A , &sioTopJtagidLo);
|
|
extAttr->mfx = (u8_t)((sioTopJtagidLo>>29)&0xF) ;
|
|
|
|
switch ((sioTopJtagidLo>>12)&0xFF)
|
|
{
|
|
case 0x31:
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A , SIO_TOP_COMM_KEY_KEY);
|
|
RR16( devAddr, SIO_PDR_UIO_IN_HI__A , &bid);
|
|
bid = (bid >> 10) & 0xf;
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A , SIO_TOP_COMM_KEY__PRE);
|
|
|
|
extAttr->hasLNA = TRUE;
|
|
extAttr->hasNTSC = FALSE;
|
|
extAttr->hasBTSC = FALSE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = FALSE;
|
|
extAttr->hasGPIO = FALSE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x33:
|
|
extAttr->hasLNA = FALSE;
|
|
extAttr->hasNTSC = FALSE;
|
|
extAttr->hasBTSC = FALSE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = FALSE;
|
|
extAttr->hasGPIO = FALSE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x45:
|
|
extAttr->hasLNA = TRUE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = FALSE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x46:
|
|
extAttr->hasLNA = FALSE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = FALSE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x41:
|
|
extAttr->hasLNA = TRUE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = TRUE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x43:
|
|
extAttr->hasLNA = FALSE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = TRUE;
|
|
extAttr->hasOOB = FALSE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = FALSE;
|
|
break;
|
|
case 0x32:
|
|
extAttr->hasLNA = TRUE;
|
|
extAttr->hasNTSC = FALSE;
|
|
extAttr->hasBTSC = FALSE;
|
|
extAttr->hasOOB = TRUE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = TRUE;
|
|
break;
|
|
case 0x34:
|
|
extAttr->hasLNA = FALSE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = TRUE;
|
|
extAttr->hasOOB = TRUE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = TRUE;
|
|
break;
|
|
case 0x42:
|
|
extAttr->hasLNA = TRUE ;
|
|
extAttr->hasNTSC = TRUE ;
|
|
extAttr->hasBTSC = TRUE ;
|
|
extAttr->hasOOB = TRUE ;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = TRUE;
|
|
break;
|
|
case 0x44:
|
|
extAttr->hasLNA = FALSE;
|
|
extAttr->hasNTSC = TRUE;
|
|
extAttr->hasBTSC = TRUE;
|
|
extAttr->hasOOB = TRUE;
|
|
extAttr->hasSMATX = TRUE;
|
|
extAttr->hasSMARX = TRUE;
|
|
extAttr->hasGPIO = TRUE;
|
|
extAttr->hasIRQN = TRUE;
|
|
break;
|
|
default:
|
|
/* Unknown device variant */
|
|
return (DRX_STS_ERROR);
|
|
break;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
|
|
/**
|
|
* \fn DRXStatus_t PowerUpDevice()
|
|
* \brief Power up device.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
* \return DRX_STS_OK Success
|
|
* \retval DRX_STS_ERROR Failure, I2C or max retries reached
|
|
*
|
|
*/
|
|
|
|
#ifndef DRXJ_MAX_RETRIES_POWERUP
|
|
#define DRXJ_MAX_RETRIES_POWERUP 10
|
|
#endif
|
|
|
|
static DRXStatus_t
|
|
PowerUpDevice( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr =(pI2CDeviceAddr_t)(NULL);
|
|
u8_t data = 0 ;
|
|
u16_t retryCount = 0;
|
|
I2CDeviceAddr_t wakeUpAddr;
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
wakeUpAddr.i2cAddr = DRXJ_WAKE_UP_KEY;
|
|
wakeUpAddr.i2cDevId = devAddr->i2cDevId;
|
|
wakeUpAddr.userData = devAddr->userData;
|
|
/* CHK_ERROR macro not used, I2C access may fail in this case: no ack
|
|
dummy write must be used to wake uop device, dummy read must be used to
|
|
reset HI state machine (avoiding actual writes) */
|
|
do
|
|
{
|
|
data = 0;
|
|
DRXBSP_I2C_WriteRead( &wakeUpAddr, 1, &data,
|
|
(pI2CDeviceAddr_t)(NULL), 0, (pu8_t)(NULL) );
|
|
DRXBSP_HST_Sleep(10);
|
|
retryCount++ ;
|
|
}while ( (DRXBSP_I2C_WriteRead( (pI2CDeviceAddr_t)(NULL), 0, (pu8_t)(NULL),
|
|
devAddr, 1, &data )
|
|
!= DRX_STS_OK ) &&
|
|
(retryCount < DRXJ_MAX_RETRIES_POWERUP) );
|
|
|
|
/* Need some recovery time .... */
|
|
DRXBSP_HST_Sleep(10);
|
|
|
|
if ( retryCount == DRXJ_MAX_RETRIES_POWERUP )
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* MPEG Output Configuration Functions - begin */
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgMPEGOutput()
|
|
* \brief Set MPEG output configuration of the device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param cfgData Pointer to mpeg output configuaration.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Configure MPEG output parameters.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgMPEGOutput( pDRXDemodInstance_t demod,
|
|
pDRXCfgMPEGOutput_t cfgData )
|
|
{
|
|
pI2CDeviceAddr_t devAddr =(pI2CDeviceAddr_t)(NULL);
|
|
pDRXJData_t extAttr =(pDRXJData_t)(NULL);
|
|
pDRXCommonAttr_t commonAttr =(pDRXCommonAttr_t)(NULL);
|
|
u16_t fecOcRegMode = 0;
|
|
u16_t fecOcRegIprMode = 0;
|
|
u16_t fecOcRegIprInvert = 0;
|
|
u32_t maxBitRate = 0;
|
|
u32_t rcnRate = 0;
|
|
u32_t nrBits = 0;
|
|
u16_t sioPdrMdCfg = 0;
|
|
/* data mask for the output data byte */
|
|
u16_t InvertDataMask = FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
|
|
FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
|
|
FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
|
|
FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
|
|
/* check arguments */
|
|
if (( demod == NULL ) ||
|
|
( cfgData == NULL ))
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
if ( cfgData->enableMPEGOutput == TRUE )
|
|
{
|
|
/* quick and dirty patch to set MPEG incase current std is not
|
|
producing MPEG */
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
break;
|
|
default:
|
|
/* not an MPEG producing std, just store MPEG cfg */
|
|
commonAttr->mpegCfg.enableMPEGOutput = cfgData->enableMPEGOutput;
|
|
commonAttr->mpegCfg.insertRSByte = cfgData->insertRSByte;
|
|
commonAttr->mpegCfg.enableParallel = cfgData->enableParallel;
|
|
commonAttr->mpegCfg.invertDATA = cfgData->invertDATA;
|
|
commonAttr->mpegCfg.invertERR = cfgData->invertERR;
|
|
commonAttr->mpegCfg.invertSTR = cfgData->invertSTR;
|
|
commonAttr->mpegCfg.invertVAL = cfgData->invertVAL;
|
|
commonAttr->mpegCfg.invertCLK = cfgData->invertCLK;
|
|
commonAttr->mpegCfg.staticCLK = cfgData->staticCLK;
|
|
commonAttr->mpegCfg.bitrate = cfgData->bitrate;
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
WR16( devAddr, FEC_OC_OCR_INVERT__A, 0);
|
|
switch (extAttr->standard)
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
WR16( devAddr, FEC_OC_FCT_USAGE__A, 7 ); /* 2048 bytes fifo ram */
|
|
WR16( devAddr, FEC_OC_TMD_CTL_UPD_RATE__A, 10);
|
|
WR16( devAddr, FEC_OC_TMD_INT_UPD_RATE__A, 10);
|
|
WR16( devAddr, FEC_OC_AVR_PARM_A__A, 5);
|
|
WR16( devAddr, FEC_OC_AVR_PARM_B__A, 7);
|
|
WR16( devAddr, FEC_OC_RCN_GAIN__A, 10);
|
|
/* Low Water Mark for synchronization */
|
|
WR16( devAddr, FEC_OC_SNC_LWM__A, 3 );
|
|
/* High Water Mark for synchronization */
|
|
WR16( devAddr, FEC_OC_SNC_HWM__A, 5 );
|
|
break;
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
nrBits = 8;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
nrBits = 7;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
nrBits = 6;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
nrBits = 5;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM16:
|
|
nrBits = 4;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* extAttr->constellation */
|
|
/* maxBitRate = symbolRate * nrBits * coef */
|
|
/* coef = 188/204 */
|
|
maxBitRate = ( extAttr->currSymbolRate / 8 ) * nrBits * 188;
|
|
/* pass through b/c Annex A/c need following settings */
|
|
case DRX_STANDARD_ITU_B:
|
|
WR16( devAddr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE);
|
|
WR16( devAddr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE);
|
|
WR16( devAddr, FEC_OC_TMD_INT_UPD_RATE__A, 5);
|
|
WR16( devAddr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE);
|
|
WR16( devAddr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE);
|
|
if (cfgData->staticCLK == TRUE)
|
|
{
|
|
WR16( devAddr, FEC_OC_RCN_GAIN__A, 0xD );
|
|
}
|
|
else
|
|
{
|
|
WR16( devAddr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE );
|
|
}
|
|
WR16( devAddr, FEC_OC_SNC_LWM__A, 2);
|
|
WR16( devAddr, FEC_OC_SNC_HWM__A, 12);
|
|
break;
|
|
default:
|
|
break;
|
|
}/* swtich (standard) */
|
|
|
|
/* Check insertion of the Reed-Solomon parity bytes */
|
|
RR16( devAddr, FEC_OC_MODE__A , &fecOcRegMode );
|
|
RR16( devAddr, FEC_OC_IPR_MODE__A, &fecOcRegIprMode );
|
|
if ( cfgData->insertRSByte == TRUE )
|
|
{
|
|
/* enable parity symbol forward */
|
|
fecOcRegMode |= FEC_OC_MODE_PARITY__M;
|
|
/* MVAL disable during parity bytes */
|
|
fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
rcnRate = 0x004854D3;
|
|
break;
|
|
case DRX_STANDARD_ITU_B:
|
|
fecOcRegMode |= FEC_OC_MODE_TRANSPARENT__M;
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
rcnRate = 0x008945E7;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
rcnRate = 0x005F64D4;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
break;
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
/* insertRSByte = TRUE -> coef = 188/188 -> 1, RS bits are in MPEG output */
|
|
rcnRate = ( Frac28 ( maxBitRate, ( u32_t )( commonAttr->sysClockFreq / 8 ) ) ) / 188;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* extAttr->standard */
|
|
}
|
|
else /* insertRSByte == FALSE */
|
|
{
|
|
/* disable parity symbol forward */
|
|
fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
|
|
/* MVAL enable during parity bytes */
|
|
fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
rcnRate = 0x0041605C;
|
|
break;
|
|
case DRX_STANDARD_ITU_B:
|
|
fecOcRegMode &= (~FEC_OC_MODE_TRANSPARENT__M);
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
rcnRate = 0x0082D6A0;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
rcnRate = 0x005AEC1A;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
break;
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
/* insertRSByte = FALSE -> coef = 188/204, RS bits not in MPEG output */
|
|
rcnRate = ( Frac28 ( maxBitRate, ( u32_t )( commonAttr->sysClockFreq / 8 ) ) ) / 204;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* extAttr->standard */
|
|
}
|
|
|
|
if ( cfgData->enableParallel == TRUE )
|
|
{ /* MPEG data output is paralel -> clear ipr_mode[0] */
|
|
fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
|
|
}
|
|
else
|
|
{ /* MPEG data output is serial -> set ipr_mode[0] */
|
|
fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
|
|
}
|
|
|
|
/* Control slective inversion of output bits */
|
|
if ( cfgData->invertDATA == TRUE )
|
|
{
|
|
fecOcRegIprInvert |= InvertDataMask;
|
|
}
|
|
else
|
|
{
|
|
fecOcRegIprInvert &= (~(InvertDataMask));
|
|
}
|
|
|
|
if ( cfgData->invertERR == TRUE )
|
|
{
|
|
fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
|
|
}
|
|
else
|
|
{
|
|
fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
|
|
}
|
|
|
|
if ( cfgData->invertSTR == TRUE )
|
|
{
|
|
fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
|
|
}
|
|
else
|
|
{
|
|
fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
|
|
}
|
|
|
|
if ( cfgData->invertVAL == TRUE )
|
|
{
|
|
fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
|
|
}
|
|
else
|
|
{
|
|
fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
|
|
}
|
|
|
|
if ( cfgData->invertCLK == TRUE )
|
|
{
|
|
fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
|
|
}
|
|
else
|
|
{
|
|
fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
|
|
}
|
|
|
|
if ( cfgData->staticCLK == TRUE ) /* Static mode */
|
|
{
|
|
u32_t dtoRate = 0;
|
|
u32_t bitRate = 0;
|
|
u16_t fecOcDtoBurstLen = 0;
|
|
u16_t fecOcDtoPeriod = 0;
|
|
|
|
fecOcDtoBurstLen = FEC_OC_DTO_BURST_LEN__PRE;
|
|
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
fecOcDtoPeriod = 4;
|
|
if ( cfgData->insertRSByte == TRUE )
|
|
{
|
|
fecOcDtoBurstLen = 208;
|
|
}
|
|
break;
|
|
case DRX_STANDARD_ITU_A:
|
|
{
|
|
u32_t symbolRateTh = 6400000;
|
|
if ( cfgData->insertRSByte == TRUE )
|
|
{
|
|
fecOcDtoBurstLen = 204;
|
|
symbolRateTh = 5900000;
|
|
}
|
|
if ( extAttr->currSymbolRate >= symbolRateTh)
|
|
{
|
|
fecOcDtoPeriod = 0;
|
|
}
|
|
else
|
|
{
|
|
fecOcDtoPeriod = 1;
|
|
}
|
|
}
|
|
break;
|
|
case DRX_STANDARD_ITU_B:
|
|
fecOcDtoPeriod = 1;
|
|
if ( cfgData->insertRSByte == TRUE )
|
|
{
|
|
fecOcDtoBurstLen = 128;
|
|
}
|
|
break;
|
|
case DRX_STANDARD_ITU_C:
|
|
fecOcDtoPeriod = 1;
|
|
if ( cfgData->insertRSByte == TRUE )
|
|
{
|
|
fecOcDtoBurstLen = 204;
|
|
}
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
bitRate = commonAttr->sysClockFreq * 1000 / (fecOcDtoPeriod + 2);
|
|
dtoRate = Frac28(bitRate, commonAttr->sysClockFreq * 1000 );
|
|
dtoRate >>= 3;
|
|
WR16 ( devAddr, FEC_OC_DTO_RATE_HI__A, (u16_t) ((dtoRate >> 16) & FEC_OC_DTO_RATE_HI__M) );
|
|
WR16 ( devAddr, FEC_OC_DTO_RATE_LO__A, (u16_t) (dtoRate & FEC_OC_DTO_RATE_LO_RATE_LO__M) );
|
|
WR16 ( devAddr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M );
|
|
WR16 ( devAddr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M );
|
|
WR16 ( devAddr, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen );
|
|
if ( extAttr->mpegOutputClockRate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO )
|
|
fecOcDtoPeriod = extAttr->mpegOutputClockRate - 1;
|
|
WR16 ( devAddr, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod );
|
|
}
|
|
else /* Dynamic mode */
|
|
{
|
|
WR16 ( devAddr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M );
|
|
WR16 ( devAddr, FEC_OC_FCT_MODE__A, 0 );
|
|
}
|
|
|
|
WR32 ( devAddr, FEC_OC_RCN_CTL_RATE_LO__A, rcnRate );
|
|
|
|
/* Write appropriate registers with requested configuration */
|
|
WR16 ( devAddr, FEC_OC_MODE__A, fecOcRegMode );
|
|
WR16 ( devAddr, FEC_OC_IPR_MODE__A, fecOcRegIprMode );
|
|
WR16 ( devAddr, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert );
|
|
|
|
/* enabling for both parallel and serial now */
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
|
|
/* Set MPEG TS pads to outputmode */
|
|
WR16 ( devAddr, SIO_PDR_MSTRT_CFG__A, 0x0013);
|
|
WR16 ( devAddr, SIO_PDR_MERR_CFG__A, 0x0013);
|
|
WR16 ( devAddr, SIO_PDR_MCLK_CFG__A,
|
|
MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B
|
|
| 0x03 << SIO_PDR_MCLK_CFG_MODE__B );
|
|
WR16 ( devAddr, SIO_PDR_MVAL_CFG__A, 0x0013);
|
|
sioPdrMdCfg = MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH << SIO_PDR_MD0_CFG_DRIVE__B
|
|
|0x03 << SIO_PDR_MD0_CFG_MODE__B;
|
|
WR16 ( devAddr, SIO_PDR_MD0_CFG__A, sioPdrMdCfg);
|
|
if ( cfgData->enableParallel == TRUE )
|
|
{ /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
|
|
sioPdrMdCfg = MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH << SIO_PDR_MD0_CFG_DRIVE__B
|
|
|0x03 << SIO_PDR_MD0_CFG_MODE__B;
|
|
WR16 ( devAddr, SIO_PDR_MD0_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD1_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD2_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD3_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD4_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD5_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD6_CFG__A, sioPdrMdCfg);
|
|
WR16 ( devAddr, SIO_PDR_MD7_CFG__A, sioPdrMdCfg);
|
|
}
|
|
else
|
|
{ /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
|
|
WR16 ( devAddr, SIO_PDR_MD1_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD2_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD3_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD4_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD5_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD6_CFG__A, 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD7_CFG__A, 0x0000);
|
|
}
|
|
/* Enable Monitor Bus output over MPEG pads and ctl input */
|
|
WR16 ( devAddr, SIO_PDR_MON_CFG__A, 0x0000);
|
|
/* Write nomagic word to enable pdr reg write */
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A, 0x0000);
|
|
}
|
|
else
|
|
{
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A , 0xFABA);
|
|
/* Set MPEG TS pads to inputmode */
|
|
WR16 ( devAddr, SIO_PDR_MSTRT_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MERR_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MCLK_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MVAL_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD0_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD1_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD2_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD3_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD4_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD5_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD6_CFG__A , 0x0000);
|
|
WR16 ( devAddr, SIO_PDR_MD7_CFG__A , 0x0000);
|
|
/* Enable Monitor Bus output over MPEG pads and ctl input */
|
|
WR16 ( devAddr, SIO_PDR_MON_CFG__A , 0x0000);
|
|
/* Write nomagic word to enable pdr reg write */
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A , 0x0000);
|
|
}
|
|
|
|
/* save values for restore after re-acquire */
|
|
commonAttr->mpegCfg.enableMPEGOutput = cfgData->enableMPEGOutput;
|
|
commonAttr->mpegCfg.insertRSByte = cfgData->insertRSByte;
|
|
commonAttr->mpegCfg.enableParallel = cfgData->enableParallel;
|
|
commonAttr->mpegCfg.invertDATA = cfgData->invertDATA;
|
|
commonAttr->mpegCfg.invertERR = cfgData->invertERR;
|
|
commonAttr->mpegCfg.invertSTR = cfgData->invertSTR;
|
|
commonAttr->mpegCfg.invertVAL = cfgData->invertVAL;
|
|
commonAttr->mpegCfg.invertCLK = cfgData->invertCLK;
|
|
commonAttr->mpegCfg.staticCLK = cfgData->staticCLK;
|
|
commonAttr->mpegCfg.bitrate = cfgData->bitrate;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgMPEGOutput()
|
|
* \brief Get MPEG output configuration of the device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param cfgData Pointer to MPEG output configuaration struct.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Retrieve MPEG output configuartion.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgMPEGOutput( pDRXDemodInstance_t demod,
|
|
pDRXCfgMPEGOutput_t cfgData )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)(NULL);
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
u32_t rateReg = 0;
|
|
u32_t data64Hi = 0;
|
|
u32_t data64Lo = 0;
|
|
|
|
if( cfgData == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
devAddr = demod->myI2CDevAddr;
|
|
commonAttr = demod->myCommonAttr;
|
|
|
|
cfgData->enableMPEGOutput = commonAttr->mpegCfg.enableMPEGOutput;
|
|
cfgData->insertRSByte = commonAttr->mpegCfg.insertRSByte;
|
|
cfgData->enableParallel = commonAttr->mpegCfg.enableParallel;
|
|
cfgData->invertDATA = commonAttr->mpegCfg.invertDATA;
|
|
cfgData->invertERR = commonAttr->mpegCfg.invertERR;
|
|
cfgData->invertSTR = commonAttr->mpegCfg.invertSTR;
|
|
cfgData->invertVAL = commonAttr->mpegCfg.invertVAL;
|
|
cfgData->invertCLK = commonAttr->mpegCfg.invertCLK;
|
|
cfgData->staticCLK = commonAttr->mpegCfg.staticCLK;
|
|
cfgData->bitrate = 0;
|
|
|
|
CHK_ERROR( CtrlLockStatus( demod, &lockStatus) );
|
|
if ( (lockStatus == DRX_LOCKED) )
|
|
{
|
|
RR32 (devAddr, FEC_OC_RCN_DYN_RATE_LO__A, &rateReg);
|
|
/* Frcn_rate = rateReg * Fsys / 2 ^ 25 */
|
|
Mult32 ( rateReg, commonAttr->sysClockFreq * 1000, &data64Hi, &data64Lo );
|
|
cfgData->bitrate = (data64Hi << 7) | (data64Lo >> 25);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* MPEG Output Configuration Functions - end */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* miscellaneous configuartions - begin */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetMPEGTEIHandling()
|
|
* \brief Activate MPEG TEI handling settings.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine should be called during a set channel of QAM/VSB
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SetMPEGTEIHandling( pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
u16_t fecOcDprMode = 0;
|
|
u16_t fecOcSncMode = 0;
|
|
u16_t fecOcEmsMode = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
RR16( devAddr, FEC_OC_DPR_MODE__A, &fecOcDprMode );
|
|
RR16( devAddr, FEC_OC_SNC_MODE__A, &fecOcSncMode );
|
|
RR16( devAddr, FEC_OC_EMS_MODE__A, &fecOcEmsMode );
|
|
|
|
/* reset to default, allow TEI bit to be changed */
|
|
fecOcDprMode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
|
|
fecOcSncMode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
|
|
FEC_OC_SNC_MODE_CORR_DISABLE__M));
|
|
fecOcEmsMode &= (~FEC_OC_EMS_MODE_MODE__M);
|
|
|
|
if ( extAttr->disableTEIhandling == TRUE )
|
|
{
|
|
/* do not change TEI bit */
|
|
fecOcDprMode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
|
|
fecOcSncMode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
|
|
( (0x2)<<(FEC_OC_SNC_MODE_ERROR_CTL__B));
|
|
fecOcEmsMode |= ((0x01)<<(FEC_OC_EMS_MODE_MODE__B));
|
|
}
|
|
|
|
WR16( devAddr, FEC_OC_DPR_MODE__A, fecOcDprMode );
|
|
WR16( devAddr, FEC_OC_SNC_MODE__A, fecOcSncMode );
|
|
WR16( devAddr, FEC_OC_EMS_MODE__A, fecOcEmsMode );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t BitReverseMPEGOutput()
|
|
* \brief Set MPEG output bit-endian settings.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine should be called during a set channel of QAM/VSB
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
BitReverseMPEGOutput ( pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
u16_t fecOcIprMode = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
RR16( devAddr, FEC_OC_IPR_MODE__A, &fecOcIprMode );
|
|
|
|
/* reset to default (normal bit order) */
|
|
fecOcIprMode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
|
|
|
|
if ( extAttr->bitReverseMpegOutout == TRUE)
|
|
{
|
|
/* reverse bit order */
|
|
fecOcIprMode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
|
|
}
|
|
|
|
WR16( devAddr, FEC_OC_IPR_MODE__A, fecOcIprMode );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t SetMPEGOutputClockRate()
|
|
* \brief Set MPEG output clock rate.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine should be called during a set channel of QAM/VSB
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SetMPEGOutputClockRate ( pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
if ( extAttr->mpegOutputClockRate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO )
|
|
{
|
|
WR16 ( devAddr, FEC_OC_DTO_PERIOD__A, extAttr->mpegOutputClockRate - 1 );
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t SetMPEGStartWidth()
|
|
* \brief Set MPEG start width.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine should be called during a set channel of QAM/VSB
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SetMPEGStartWidth ( pDRXDemodInstance_t demod )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
u16_t fecOcCommMb = 0;
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
commonAttr = demod->myCommonAttr;
|
|
|
|
if ((commonAttr->mpegCfg.staticCLK == TRUE) && (commonAttr->mpegCfg.enableParallel == FALSE))
|
|
{
|
|
RR16 ( devAddr, FEC_OC_COMM_MB__A, &fecOcCommMb );
|
|
fecOcCommMb &= ~FEC_OC_COMM_MB_CTL_ON;
|
|
if ( extAttr->mpegStartWidth == DRXJ_MPEG_START_WIDTH_8CLKCYC )
|
|
{
|
|
fecOcCommMb |= FEC_OC_COMM_MB_CTL_ON;
|
|
}
|
|
WR16 ( devAddr, FEC_OC_COMM_MB__A, fecOcCommMb);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgMpegOutputMisc()
|
|
* \brief Set miscellaneous configuartions
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param cfgData pDRXJCfgMisc_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine can be used to set configuartion options that are DRXJ
|
|
* specific and/or added to the requirements at a late stage.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgMpegOutputMisc(
|
|
pDRXDemodInstance_t demod,
|
|
pDRXJCfgMpegOutputMisc_t cfgData )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
/*
|
|
Set disable TEI bit handling flag.
|
|
TEI must be left untouched by device in case of BER measurements using
|
|
external equipment that is unable to ignore the TEI bit in the TS.
|
|
Default will FALSE (enable TEI bit handling).
|
|
Reverse output bit order. Default is FALSE (msb on MD7 (parallel) or out first (serial)).
|
|
Set clock rate. Default is auto that is derived from symbol rate.
|
|
The flags and values will also be used to set registers during a set channel.
|
|
*/
|
|
extAttr->disableTEIhandling = cfgData->disableTEIHandling;
|
|
extAttr->bitReverseMpegOutout = cfgData->bitReverseMpegOutout;
|
|
extAttr->mpegOutputClockRate = cfgData->mpegOutputClockRate;
|
|
extAttr->mpegStartWidth = cfgData->mpegStartWidth;
|
|
/* Don't care what the active standard is, activate setting immediatly */
|
|
CHK_ERROR ( SetMPEGTEIHandling( demod ) );
|
|
CHK_ERROR ( BitReverseMPEGOutput( demod ) );
|
|
CHK_ERROR ( SetMPEGOutputClockRate( demod ) );
|
|
CHK_ERROR ( SetMPEGStartWidth ( demod ) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgMpegOutputMisc()
|
|
* \brief Get miscellaneous configuartions.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param cfgData Pointer to DRXJCfgMisc_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine can be used to retreive the current setting of the configuartion
|
|
* options that are DRXJ specific and/or added to the requirements at a
|
|
* late stage.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgMpegOutputMisc(
|
|
pDRXDemodInstance_t demod,
|
|
pDRXJCfgMpegOutputMisc_t cfgData )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
u16_t data = 0;
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
cfgData->disableTEIHandling = extAttr->disableTEIhandling;
|
|
cfgData->bitReverseMpegOutout = extAttr->bitReverseMpegOutout;
|
|
cfgData->mpegStartWidth = extAttr->mpegStartWidth;
|
|
if (extAttr->mpegOutputClockRate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
|
|
{
|
|
cfgData->mpegOutputClockRate = extAttr->mpegOutputClockRate;
|
|
}
|
|
else
|
|
{
|
|
RR16 ( demod->myI2CDevAddr, FEC_OC_DTO_PERIOD__A, &data );
|
|
cfgData->mpegOutputClockRate = (DRXJMpegOutputClockRate_t) (data + 1);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgHwCfg()
|
|
* \brief Get HW configuartions.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param cfgData Pointer to Bool.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* This routine can be used to retreive the current setting of the configuartion
|
|
* options that are DRXJ specific and/or added to the requirements at a
|
|
* late stage.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgHwCfg( pDRXDemodInstance_t demod,
|
|
pDRXJCfgHwCfg_t cfgData )
|
|
{
|
|
u16_t data = 0;
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
WR16 ( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0xFABA);
|
|
RR16 ( demod->myI2CDevAddr, SIO_PDR_OHW_CFG__A, &data );
|
|
WR16 ( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
|
|
|
|
cfgData->i2cSpeed = (DRXJI2CSpeed_t)((data >> 6) & 0x1);
|
|
cfgData->xtalFreq = (DRXJXtalFreq_t)(data & 0x3);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*----------------------------------------------------------------------------*/
|
|
/* miscellaneous configuartions - end */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* UIO Configuration Functions - begin */
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetUIOCfg()
|
|
* \brief Configure modus oprandi UIO.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param UIOCfg Pointer to a configuration setting for a certain UIO.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetUIOCfg( pDRXDemodInstance_t demod, pDRXUIOCfg_t UIOCfg )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
|
|
if (( UIOCfg == NULL ) || ( demod == NULL ))
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
switch ( UIOCfg->uio ) {
|
|
/*====================================================================*/
|
|
case DRX_UIO1 :
|
|
/* DRX_UIO1: SMA_TX UIO-1 */
|
|
if (extAttr->hasSMATX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
switch ( UIOCfg->mode )
|
|
{
|
|
case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
|
|
case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
|
|
case DRX_UIO_MODE_READWRITE:
|
|
extAttr->uioSmaTxMode = UIOCfg->mode;
|
|
break;
|
|
case DRX_UIO_MODE_DISABLE:
|
|
extAttr->uioSmaTxMode = UIOCfg->mode;
|
|
/* pad configuration register is set 0 - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, 0 );
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
} /* switch ( UIOCfg->mode ) */
|
|
break;
|
|
/*====================================================================*/
|
|
case DRX_UIO2 :
|
|
/* DRX_UIO2: SMA_RX UIO-2 */
|
|
if (extAttr->hasSMARX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
switch ( UIOCfg->mode )
|
|
{
|
|
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
|
case DRX_UIO_MODE_READWRITE:
|
|
extAttr->uioSmaRxMode = UIOCfg->mode;
|
|
break;
|
|
case DRX_UIO_MODE_DISABLE:
|
|
extAttr->uioSmaRxMode = UIOCfg->mode;
|
|
/* pad configuration register is set 0 - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, 0 );
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
} /* switch ( UIOCfg->mode ) */
|
|
break;
|
|
/*====================================================================*/
|
|
case DRX_UIO3 :
|
|
/* DRX_UIO3: GPIO UIO-3 */
|
|
if (extAttr->hasGPIO != TRUE)
|
|
return DRX_STS_ERROR;
|
|
switch ( UIOCfg->mode )
|
|
{
|
|
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
|
case DRX_UIO_MODE_READWRITE:
|
|
extAttr->uioGPIOMode = UIOCfg->mode;
|
|
break;
|
|
case DRX_UIO_MODE_DISABLE:
|
|
extAttr->uioGPIOMode = UIOCfg->mode;
|
|
/* pad configuration register is set 0 - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, 0 );
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
} /* switch ( UIOCfg->mode ) */
|
|
break;
|
|
/*====================================================================*/
|
|
case DRX_UIO4 :
|
|
/* DRX_UIO4: IRQN UIO-4 */
|
|
if (extAttr->hasIRQN != TRUE)
|
|
return DRX_STS_ERROR;
|
|
switch ( UIOCfg->mode )
|
|
{
|
|
case DRX_UIO_MODE_READWRITE:
|
|
extAttr->uioIRQNMode = UIOCfg->mode;
|
|
break;
|
|
case DRX_UIO_MODE_DISABLE:
|
|
/* pad configuration register is set 0 - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, 0 );
|
|
extAttr->uioIRQNMode = UIOCfg->mode;
|
|
break;
|
|
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
} /* switch ( UIOCfg->mode ) */
|
|
break;
|
|
/*====================================================================*/
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
} /* switch ( UIOCfg->uio ) */
|
|
|
|
/* Write magic word to disable pdr reg write */
|
|
WR16 ( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetUIOCfg()
|
|
* \brief Get modus oprandi UIO.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param UIOCfg Pointer to a configuration setting for a certain UIO.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetUIOCfg( pDRXDemodInstance_t demod, pDRXUIOCfg_t UIOCfg )
|
|
{
|
|
|
|
pDRXJData_t extAttr = (pDRXJData_t) NULL;
|
|
pDRXUIOMode_t UIOMode[4] = {NULL};
|
|
pBool_t UIOAvailable[4] = {NULL};
|
|
|
|
extAttr = demod->myExtAttr;
|
|
|
|
UIOMode[DRX_UIO1] = &extAttr->uioSmaTxMode;
|
|
UIOMode[DRX_UIO2] = &extAttr->uioSmaRxMode;
|
|
UIOMode[DRX_UIO3] = &extAttr->uioGPIOMode;
|
|
UIOMode[DRX_UIO4] = &extAttr->uioIRQNMode;
|
|
|
|
UIOAvailable[DRX_UIO1] = &extAttr->hasSMATX;
|
|
UIOAvailable[DRX_UIO2] = &extAttr->hasSMARX;
|
|
UIOAvailable[DRX_UIO3] = &extAttr->hasGPIO;
|
|
UIOAvailable[DRX_UIO4] = &extAttr->hasIRQN;
|
|
|
|
if ( UIOCfg == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
if ( ( UIOCfg->uio > DRX_UIO4 ) ||
|
|
( UIOCfg->uio < DRX_UIO1 ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
if( *UIOAvailable[UIOCfg->uio] == FALSE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
UIOCfg->mode = *UIOMode[ UIOCfg->uio ];
|
|
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlUIOWrite()
|
|
* \brief Write to a UIO.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param UIOData Pointer to data container for a certain UIO.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlUIOWrite( pDRXDemodInstance_t demod,
|
|
pDRXUIOData_t UIOData)
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
u16_t pinCfgValue = 0;
|
|
u16_t value = 0;
|
|
|
|
if (( UIOData == NULL ) || ( demod == NULL ))
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
switch ( UIOData->uio ) {
|
|
/*====================================================================*/
|
|
case DRX_UIO1:
|
|
/* DRX_UIO1: SMA_TX UIO-1 */
|
|
if (extAttr->hasSMATX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
if ( ( extAttr->uioSmaTxMode != DRX_UIO_MODE_READWRITE )
|
|
&& ( extAttr->uioSmaTxMode != DRX_UIO_MODE_FIRMWARE_SAW ) )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0113;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - output mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, pinCfgValue );
|
|
|
|
/* use corresponding bit in io data output registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value );
|
|
if (UIOData->value == FALSE)
|
|
{
|
|
value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
|
|
} else {
|
|
value |= 0x8000; /* write one to 15th bit - 1st UIO */
|
|
}
|
|
/* write back to io data output register */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value );
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_UIO2:
|
|
/* DRX_UIO2: SMA_RX UIO-2 */
|
|
if (extAttr->hasSMARX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
if ( extAttr->uioSmaRxMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0113;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - output mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, pinCfgValue );
|
|
|
|
/* use corresponding bit in io data output registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value );
|
|
if (UIOData->value == FALSE)
|
|
{
|
|
value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
|
|
} else {
|
|
value |= 0x4000; /* write one to 14th bit - 2nd UIO */
|
|
}
|
|
/* write back to io data output register */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value );
|
|
break;
|
|
/*====================================================================*/
|
|
case DRX_UIO3:
|
|
/* DRX_UIO3: ASEL UIO-3 */
|
|
if (extAttr->hasGPIO != TRUE)
|
|
return DRX_STS_ERROR;
|
|
if ( extAttr->uioGPIOMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0113;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - output mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, pinCfgValue );
|
|
|
|
/* use corresponding bit in io data output registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_HI__A, &value );
|
|
if (UIOData->value == FALSE)
|
|
{
|
|
value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
|
|
} else {
|
|
value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
|
|
}
|
|
/* write back to io data output register */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_HI__A, value );
|
|
break;
|
|
/*=====================================================================*/
|
|
case DRX_UIO4:
|
|
/* DRX_UIO4: IRQN UIO-4 */
|
|
if (extAttr->hasIRQN != TRUE)
|
|
return DRX_STS_ERROR;
|
|
|
|
if ( extAttr->uioIRQNMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0113;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - output mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, pinCfgValue );
|
|
|
|
/* use corresponding bit in io data output registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, &value );
|
|
if (UIOData->value == FALSE)
|
|
{
|
|
value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
|
|
} else {
|
|
value |= 0x1000; /* write one to 12th bit - 4th UIO */
|
|
}
|
|
/* write back to io data output register */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_UIO_OUT_LO__A, value );
|
|
break;
|
|
/*=====================================================================*/
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
} /* switch ( UIOData->uio ) */
|
|
|
|
/* Write magic word to disable pdr reg write */
|
|
WR16 ( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
|
|
/**
|
|
*\fn DRXStatus_t CtrlUIORead
|
|
*\brief Read from a UIO.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param UIOData Pointer to data container for a certain UIO.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlUIORead( pDRXDemodInstance_t demod,
|
|
pDRXUIOData_t UIOData)
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
u16_t pinCfgValue = 0;
|
|
u16_t value = 0;
|
|
|
|
if (( UIOData == NULL ) || ( demod == NULL ))
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
switch ( UIOData->uio ) {
|
|
/*====================================================================*/
|
|
case DRX_UIO1:
|
|
/* DRX_UIO1: SMA_TX UIO-1 */
|
|
if (extAttr->hasSMATX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
|
|
if ( extAttr->uioSmaTxMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0110;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, pinCfgValue );
|
|
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value );
|
|
if ( (value & 0x8000) != 0 ) /* check 15th bit - 1st UIO */
|
|
{
|
|
UIOData->value = TRUE;
|
|
} else {
|
|
UIOData->value = FALSE;
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_UIO2:
|
|
/* DRX_UIO2: SMA_RX UIO-2 */
|
|
if (extAttr->hasSMARX != TRUE)
|
|
return DRX_STS_ERROR;
|
|
|
|
if ( extAttr->uioSmaRxMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0110;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_RX_CFG__A, pinCfgValue );
|
|
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value );
|
|
|
|
if ( (value & 0x4000) != 0 ) /* check 14th bit - 2nd UIO */
|
|
{
|
|
UIOData->value = TRUE;
|
|
} else {
|
|
UIOData->value = FALSE;
|
|
}
|
|
break;
|
|
/*=====================================================================*/
|
|
case DRX_UIO3:
|
|
/* DRX_UIO3: GPIO UIO-3 */
|
|
if (extAttr->hasGPIO != TRUE)
|
|
return DRX_STS_ERROR;
|
|
|
|
if ( extAttr->uioGPIOMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0110;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_GPIO_CFG__A, pinCfgValue );
|
|
|
|
/* read io input data registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_IN_HI__A, &value );
|
|
if ( (value & 0x0004) != 0 ) /* check 2nd bit - 3rd UIO */
|
|
{
|
|
UIOData->value = TRUE;
|
|
} else {
|
|
UIOData->value = FALSE;
|
|
}
|
|
break;
|
|
/*=====================================================================*/
|
|
case DRX_UIO4:
|
|
/* DRX_UIO4: IRQN UIO-4 */
|
|
if (extAttr->hasIRQN != TRUE)
|
|
return DRX_STS_ERROR;
|
|
|
|
if ( extAttr->uioIRQNMode != DRX_UIO_MODE_READWRITE )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
pinCfgValue = 0;
|
|
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
|
|
pinCfgValue |= 0x0110;
|
|
/* io_pad_cfg_mode output mode is drive always */
|
|
/* io_pad_cfg_drive is set to power 2 (23 mA) */
|
|
|
|
/* write to io pad configuration register - input mode */
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_IRQN_CFG__A, pinCfgValue );
|
|
|
|
/* read io input data registar */
|
|
RR16( demod->myI2CDevAddr, SIO_PDR_UIO_IN_LO__A, &value );
|
|
if ( (value & 0x1000) != 0 ) /* check 12th bit - 4th UIO */
|
|
{
|
|
UIOData->value = TRUE;
|
|
} else {
|
|
UIOData->value = FALSE;
|
|
}
|
|
break;
|
|
/*====================================================================*/
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
} /* switch ( UIOData->uio ) */
|
|
|
|
/* Write magic word to disable pdr reg write */
|
|
WR16 ( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
/* UIO Configuration Functions - end */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* I2C Bridge Functions - begin */
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlI2CBridge()
|
|
* \brief Open or close the I2C switch to tuner.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param bridgeClosed Pointer to bool indication if bridge is closed not.
|
|
* \return DRXStatus_t.
|
|
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlI2CBridge( pDRXDemodInstance_t demod,
|
|
pBool_t bridgeClosed )
|
|
{
|
|
DRXJHiCmd_t hiCmd;
|
|
u16_t result = 0;
|
|
|
|
/* check arguments */
|
|
if (bridgeClosed == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
hiCmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
|
|
hiCmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
|
|
if (*bridgeClosed == TRUE)
|
|
{
|
|
hiCmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
|
|
}
|
|
else
|
|
{
|
|
hiCmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
|
|
}
|
|
|
|
return HICommand( demod -> myI2CDevAddr, &hiCmd, &result);
|
|
}
|
|
/*----------------------------------------------------------------------------*/
|
|
/* I2C Bridge Functions - end */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Smart antenna Functions - begin */
|
|
/*----------------------------------------------------------------------------*/
|
|
/**
|
|
* \fn DRXStatus_t SmartAntInit()
|
|
* \brief Initialize Smart Antenna.
|
|
* \param pointer to DRXDemodInstance_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SmartAntInit(pDRXDemodInstance_t demod)
|
|
{
|
|
u16_t data = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXUIOCfg_t UIOCfg = {DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA};
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
/* init smart antenna */
|
|
RR16( devAddr, SIO_SA_TX_COMMAND__A, &data );
|
|
if (extAttr->smartAntInverted)
|
|
WR16( devAddr, SIO_SA_TX_COMMAND__A,
|
|
(data | SIO_SA_TX_COMMAND_TX_INVERT__M )
|
|
| SIO_SA_TX_COMMAND_TX_ENABLE__M );
|
|
else
|
|
WR16( devAddr, SIO_SA_TX_COMMAND__A,
|
|
(data & (~SIO_SA_TX_COMMAND_TX_INVERT__M))
|
|
| SIO_SA_TX_COMMAND_TX_ENABLE__M );
|
|
|
|
/* config SMA_TX pin to smart antenna mode*/
|
|
CHK_ERROR( CtrlSetUIOCfg( demod, &UIOCfg ) );
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_TX_CFG__A, 0x13 );
|
|
WR16( demod->myI2CDevAddr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03 );
|
|
|
|
/* Write magic word to disable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000 );
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgSmartAnt()
|
|
* \brief Set Smart Antenna.
|
|
* \param pointer to DRXJCfgSmartAnt_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgSmartAnt ( pDRXDemodInstance_t demod, pDRXJCfgSmartAnt_t smartAnt )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
u16_t data = 0;
|
|
u32_t startTime = 0;
|
|
static Bool_t bitInverted = FALSE;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* check arguments */
|
|
if ( smartAnt == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
if ( bitInverted != extAttr->smartAntInverted
|
|
|| extAttr->uioSmaTxMode != DRX_UIO_MODE_FIRMWARE_SMA)
|
|
{
|
|
CHK_ERROR(SmartAntInit(demod));
|
|
bitInverted = extAttr->smartAntInverted;
|
|
}
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
|
|
switch (smartAnt->io)
|
|
{
|
|
case DRXJ_SMT_ANT_OUTPUT:
|
|
/* enable Tx if Mode B (input) is supported */
|
|
/*
|
|
RR16( devAddr, SIO_SA_TX_COMMAND__A, &data );
|
|
WR16( devAddr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
|
|
*/
|
|
startTime = DRXBSP_HST_Clock();
|
|
do{
|
|
RR16( devAddr, SIO_SA_TX_STATUS__A, &data );
|
|
} while ( (data & SIO_SA_TX_STATUS_BUSY__M) && ( (DRXBSP_HST_Clock() - startTime) < DRXJ_MAX_WAITTIME ) );
|
|
|
|
if ( data & SIO_SA_TX_STATUS_BUSY__M )
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* write to smart antenna configuration register */
|
|
WR16( devAddr, SIO_SA_TX_DATA0__A, 0x9200
|
|
| ((smartAnt->ctrlData & 0x0001) << 8)
|
|
| ((smartAnt->ctrlData & 0x0002) << 10)
|
|
| ((smartAnt->ctrlData & 0x0004) << 12)
|
|
);
|
|
WR16( devAddr, SIO_SA_TX_DATA1__A, 0x4924
|
|
| ((smartAnt->ctrlData & 0x0008) >> 2)
|
|
| ((smartAnt->ctrlData & 0x0010) )
|
|
| ((smartAnt->ctrlData & 0x0020) << 2)
|
|
| ((smartAnt->ctrlData & 0x0040) << 4)
|
|
| ((smartAnt->ctrlData & 0x0080) << 6)
|
|
);
|
|
WR16( devAddr, SIO_SA_TX_DATA2__A, 0x2492
|
|
| ((smartAnt->ctrlData & 0x0100) >> 8)
|
|
| ((smartAnt->ctrlData & 0x0200) >> 6)
|
|
| ((smartAnt->ctrlData & 0x0400) >> 4)
|
|
| ((smartAnt->ctrlData & 0x0800) >> 2)
|
|
| ((smartAnt->ctrlData & 0x1000) )
|
|
| ((smartAnt->ctrlData & 0x2000) << 2)
|
|
);
|
|
WR16( devAddr, SIO_SA_TX_DATA3__A, 0xff8d );
|
|
|
|
/* trigger the sending */
|
|
WR16( devAddr, SIO_SA_TX_LENGTH__A, 56 );
|
|
|
|
break;
|
|
case DRXJ_SMT_ANT_INPUT:
|
|
/* disable Tx if Mode B (input) is supported */
|
|
/*
|
|
RR16( devAddr, SIO_SA_TX_COMMAND__A, &data );
|
|
WR16( devAddr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
|
|
*/
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( demod->myI2CDevAddr, SIO_TOP_COMM_KEY__A, 0x0000 );
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
static DRXStatus_t
|
|
SCUCommand( pI2CDeviceAddr_t devAddr, pDRXJSCUCmd_t cmd )
|
|
{
|
|
u16_t curCmd = 0;
|
|
u32_t startTime = 0;
|
|
|
|
/* Check param */
|
|
if ( cmd == NULL )
|
|
return (DRX_STS_INVALID_ARG);
|
|
|
|
/* Wait until SCU command interface is ready to receive command */
|
|
RR16( devAddr, SCU_RAM_COMMAND__A, &curCmd );
|
|
if ( curCmd != DRX_SCU_READY )
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
switch ( cmd->parameterLen )
|
|
{
|
|
case 5:
|
|
WR16( devAddr, SCU_RAM_PARAM_4__A , *(cmd->parameter + 4)); /* fallthrough */
|
|
case 4:
|
|
WR16( devAddr, SCU_RAM_PARAM_3__A , *(cmd->parameter + 3)); /* fallthrough */
|
|
case 3:
|
|
WR16( devAddr, SCU_RAM_PARAM_2__A , *(cmd->parameter + 2)); /* fallthrough */
|
|
case 2:
|
|
WR16( devAddr, SCU_RAM_PARAM_1__A , *(cmd->parameter + 1)); /* fallthrough */
|
|
case 1:
|
|
WR16( devAddr, SCU_RAM_PARAM_0__A , *(cmd->parameter + 0)); /* fallthrough */
|
|
case 0:
|
|
/* do nothing */
|
|
break;
|
|
default:
|
|
/* this number of parameters is not supported */
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
WR16( devAddr, SCU_RAM_COMMAND__A, cmd->command );
|
|
|
|
/* Wait until SCU has processed command */
|
|
startTime = DRXBSP_HST_Clock();
|
|
do{
|
|
RR16( devAddr, SCU_RAM_COMMAND__A, &curCmd );
|
|
} while ( ! ( curCmd == DRX_SCU_READY ) && ( (DRXBSP_HST_Clock() - startTime) < DRXJ_MAX_WAITTIME ) );
|
|
|
|
if ( curCmd != DRX_SCU_READY )
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* read results */
|
|
if ( (cmd->resultLen > 0) && (cmd->result != NULL) )
|
|
{
|
|
s16_t err;
|
|
|
|
switch ( cmd->resultLen )
|
|
{
|
|
case 4:
|
|
RR16( devAddr, SCU_RAM_PARAM_3__A , cmd->result + 3); /* fallthrough */
|
|
case 3:
|
|
RR16( devAddr, SCU_RAM_PARAM_2__A , cmd->result + 2); /* fallthrough */
|
|
case 2:
|
|
RR16( devAddr, SCU_RAM_PARAM_1__A , cmd->result + 1); /* fallthrough */
|
|
case 1:
|
|
RR16( devAddr, SCU_RAM_PARAM_0__A , cmd->result + 0); /* fallthrough */
|
|
case 0:
|
|
/* do nothing */
|
|
break;
|
|
default:
|
|
/* this number of parameters is not supported */
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
|
|
/* Check if an error was reported by SCU */
|
|
err = cmd->result[0];
|
|
|
|
/* check a few fixed error codes */
|
|
if ( ( err == (s16_t)SCU_RAM_PARAM_0_RESULT_UNKSTD )
|
|
|| ( err == (s16_t)SCU_RAM_PARAM_0_RESULT_UNKCMD )
|
|
|| ( err == (s16_t)SCU_RAM_PARAM_0_RESULT_INVPAR )
|
|
|| ( err == (s16_t)SCU_RAM_PARAM_0_RESULT_SIZE )
|
|
)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
/* here it is assumed that negative means error, and positive no error */
|
|
else if ( err < 0 )
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return DRX_STS_OK;
|
|
}
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_SCUAtomicReadWriteBlock()
|
|
* \brief Basic access routine for SCU atomic read or write access
|
|
* \param devAddr pointer to i2c dev address
|
|
* \param addr destination/source address
|
|
* \param datasize size of data buffer in bytes
|
|
* \param data pointer to data buffer
|
|
* \return DRXStatus_t
|
|
* \retval DRX_STS_OK Succes
|
|
* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
|
|
*
|
|
*/
|
|
#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
|
|
static
|
|
DRXStatus_t DRXJ_DAP_SCU_AtomicReadWriteBlock (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t datasize, /* max 30 bytes because the limit of SCU parameter */
|
|
pu8_t data,
|
|
Bool_t readFlag)
|
|
{
|
|
DRXJSCUCmd_t scuCmd;
|
|
u16_t setParamParameters[15];
|
|
u16_t cmdResult[15];
|
|
|
|
/* Parameter check */
|
|
if ( ( data == NULL ) ||
|
|
( devAddr == NULL ) ||
|
|
( (datasize%2)!= 0 ) ||
|
|
( (datasize/2) > 16 )
|
|
)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
setParamParameters[1] = (u16_t)ADDR_AT_SCU_SPACE (addr);
|
|
if (readFlag) /* read */
|
|
{
|
|
setParamParameters[0] = ((~(0x0080)) & datasize);
|
|
scuCmd.parameterLen = 2;
|
|
scuCmd.resultLen = datasize/2 + 2;
|
|
} else {
|
|
int i = 0;
|
|
|
|
setParamParameters[0] = 0x0080 | datasize;
|
|
for (i = 0; i < (datasize/2); i++)
|
|
{
|
|
setParamParameters[i+2] = (data[2*i] | (data[(2*i)+1]<<8));
|
|
}
|
|
scuCmd.parameterLen = datasize / 2 + 2;
|
|
scuCmd.resultLen = 1;
|
|
}
|
|
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_TOP | SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
|
|
scuCmd.result = cmdResult;
|
|
scuCmd.parameter = setParamParameters;
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
|
|
if ( readFlag==TRUE )
|
|
{
|
|
int i = 0;
|
|
/* read data from buffer */
|
|
for (i = 0; i < (datasize/2); i++)
|
|
{
|
|
data[2*i] = (u8_t) (scuCmd.result[i+2] & 0xFF);
|
|
data[(2*i) + 1] = (u8_t) (scuCmd.result[i+2] >> 8 );
|
|
}
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_AtomicReadReg16()
|
|
* \brief Atomic read of 16 bits words
|
|
*/
|
|
static
|
|
DRXStatus_t DRXJ_DAP_SCU_AtomicReadReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
pu16_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
u8_t buf[2];
|
|
DRXStatus_t rc = DRX_STS_ERROR;
|
|
u16_t word = 0;
|
|
|
|
if (!data)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
rc = DRXJ_DAP_SCU_AtomicReadWriteBlock ( devAddr, addr,
|
|
2, buf, TRUE);
|
|
|
|
word = (u16_t)(buf[0] + (buf[1] << 8));
|
|
|
|
*data = word;
|
|
|
|
return rc;
|
|
}
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t DRXJ_DAP_SCU_AtomicWriteReg16()
|
|
* \brief Atomic read of 16 bits words
|
|
*/
|
|
static
|
|
DRXStatus_t DRXJ_DAP_SCU_AtomicWriteReg16 (
|
|
pI2CDeviceAddr_t devAddr,
|
|
DRXaddr_t addr,
|
|
u16_t data,
|
|
DRXflags_t flags)
|
|
{
|
|
u8_t buf[2];
|
|
DRXStatus_t rc = DRX_STS_ERROR;
|
|
|
|
buf[0] = (u8_t) (data & 0xff);
|
|
buf[1] = (u8_t) ((data >> 8) & 0xff);
|
|
|
|
rc = DRXJ_DAP_SCU_AtomicReadWriteBlock ( devAddr, addr,
|
|
2, buf, FALSE);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static DRXStatus_t
|
|
CtrlI2CWriteRead( pDRXDemodInstance_t demod,
|
|
pDRXI2CData_t i2cData )
|
|
{
|
|
return (DRX_STS_FUNC_NOT_AVAILABLE);
|
|
}
|
|
|
|
DRXStatus_t
|
|
TunerI2CWriteRead( pTUNERInstance_t tuner,
|
|
pI2CDeviceAddr_t wDevAddr,
|
|
u16_t wCount,
|
|
pu8_t wData,
|
|
pI2CDeviceAddr_t rDevAddr,
|
|
u16_t rCount,
|
|
pu8_t rData)
|
|
{
|
|
pDRXDemodInstance_t demod;
|
|
DRXI2CData_t i2cData = { 2, wDevAddr, wCount, wData, rDevAddr, rCount, rData };
|
|
|
|
demod = (pDRXDemodInstance_t) (tuner->myCommonAttr->myUserData);
|
|
|
|
return ( CtrlI2CWriteRead( demod, &i2cData ) );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \brief Measure result of ADC synchronisation
|
|
* \param demod demod instance
|
|
* \param count (returned) count
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK Success
|
|
* \retval DRX_STS_ERROR Failure: I2C error
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
ADCSyncMeasurement( pDRXDemodInstance_t demod,
|
|
pu16_t count )
|
|
{
|
|
u16_t data = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Start measurement */
|
|
WR16( devAddr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
|
|
WR16( devAddr, IQM_AF_START_LOCK__A, 1);
|
|
|
|
/* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
|
|
CHK_ERROR( DRXBSP_HST_Sleep(1));
|
|
|
|
*count = 0;
|
|
RR16( devAddr, IQM_AF_PHASE0__A, &data);
|
|
if ( data == 127 )
|
|
{
|
|
*count = *count+1;
|
|
}
|
|
RR16( devAddr, IQM_AF_PHASE1__A, &data);
|
|
if ( data == 127 )
|
|
{
|
|
*count = *count+1;
|
|
}
|
|
RR16( devAddr, IQM_AF_PHASE2__A, &data);
|
|
if ( data == 127 )
|
|
{
|
|
*count = *count+1;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \brief Synchronize analog and digital clock domains
|
|
* \param demod demod instance
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK Success
|
|
* \retval DRX_STS_ERROR Failure: I2C error or failure to synchronize
|
|
*
|
|
* An IQM reset will also reset the results of this synchronization.
|
|
* After an IQM reset this routine needs to be called again.
|
|
*
|
|
*/
|
|
|
|
static DRXStatus_t
|
|
ADCSynchronization( pDRXDemodInstance_t demod )
|
|
{
|
|
u16_t count = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
CHK_ERROR( ADCSyncMeasurement( demod, &count ));
|
|
|
|
if (count==1)
|
|
{
|
|
/* Try sampling on a diffrent edge */
|
|
u16_t clkNeg = 0;
|
|
|
|
RR16( devAddr, IQM_AF_CLKNEG__A, &clkNeg);
|
|
|
|
clkNeg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
|
|
WR16( devAddr, IQM_AF_CLKNEG__A, clkNeg);
|
|
|
|
CHK_ERROR( ADCSyncMeasurement( demod, &count ));
|
|
}
|
|
|
|
if ( count < 2 )
|
|
{
|
|
/* TODO: implement fallback scenarios */
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \brief Configure IQM AF registers
|
|
* \param demod instance of demodulator.
|
|
* \param active
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
IQMSetAf ( pDRXDemodInstance_t demod, Bool_t active )
|
|
{
|
|
u16_t data = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Configure IQM */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
if( !active )
|
|
{
|
|
data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
|
|
);
|
|
} else /* active */
|
|
{
|
|
data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE
|
|
);
|
|
}
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
static DRXStatus_t
|
|
CtrlSetCfgATVOutput( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvOutput_t outputCfg );
|
|
|
|
/**
|
|
* \brief set configuration of pin-safe mode
|
|
* \param demod instance of demodulator.
|
|
* \param enable boolean; TRUE: activate pin-safe mode, FALSE: de-activate p.s.m.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgPdrSafeMode ( pDRXDemodInstance_t demod,
|
|
pBool_t enable )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t) NULL;
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) NULL;
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t) NULL;
|
|
|
|
if ( enable == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod->myExtAttr;
|
|
commonAttr = demod->myCommonAttr;
|
|
|
|
/* Write magic word to enable pdr reg write */
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
|
|
if ( *enable == TRUE )
|
|
{
|
|
Bool_t bridgeEnabled = FALSE;
|
|
|
|
/* MPEG pins to input */
|
|
WR16 ( devAddr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
|
|
/* PD_I2C_SDA2 Bridge off, Port2 Inactive
|
|
PD_I2C_SCL2 Bridge off, Port2 Inactive */
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeEnabled ) );
|
|
WR16 ( devAddr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
|
|
/* PD_GPIO Store and set to input
|
|
PD_VSYNC Store and set to input
|
|
PD_SMA_RX Store and set to input
|
|
PD_SMA_TX Store and set to input */
|
|
RR16 ( devAddr, SIO_PDR_GPIO_CFG__A, &extAttr->pdrSafeRestoreValGpio );
|
|
RR16 ( devAddr, SIO_PDR_VSYNC_CFG__A, &extAttr->pdrSafeRestoreValVSync );
|
|
RR16 ( devAddr, SIO_PDR_SMA_RX_CFG__A, &extAttr->pdrSafeRestoreValSmaRx );
|
|
RR16 ( devAddr, SIO_PDR_SMA_TX_CFG__A, &extAttr->pdrSafeRestoreValSmaTx );
|
|
WR16 ( devAddr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
|
|
/* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
|
|
PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
|
|
CHK_ERROR( IQMSetAf ( demod, FALSE ) );
|
|
|
|
/* PD_CVBS Analog DAC output, standby mode
|
|
PD_SIF Analog DAC output, standby mode */
|
|
WR16 ( devAddr, ATV_TOP_STDBY__A, ( ATV_TOP_STDBY_SIF_STDBY_STANDBY &
|
|
(~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) ) );
|
|
|
|
/* PD_I2S_CL Input
|
|
PD_I2S_DA Input
|
|
PD_I2S_WS Input */
|
|
WR16 ( devAddr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
WR16 ( devAddr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE );
|
|
}
|
|
else
|
|
{
|
|
/* No need to restore MPEG pins;
|
|
is done in SetStandard/SetChannel */
|
|
|
|
/* PD_I2C_SDA2 Port2 active
|
|
PD_I2C_SCL2 Port2 active */
|
|
WR16 ( devAddr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE );
|
|
WR16 ( devAddr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE );
|
|
|
|
/* PD_GPIO Restore
|
|
PD_VSYNC Restore
|
|
PD_SMA_RX Restore
|
|
PD_SMA_TX Restore */
|
|
WR16 ( devAddr, SIO_PDR_GPIO_CFG__A, extAttr->pdrSafeRestoreValGpio );
|
|
WR16 ( devAddr, SIO_PDR_VSYNC_CFG__A, extAttr->pdrSafeRestoreValVSync );
|
|
WR16 ( devAddr, SIO_PDR_SMA_RX_CFG__A, extAttr->pdrSafeRestoreValSmaRx );
|
|
WR16 ( devAddr, SIO_PDR_SMA_TX_CFG__A, extAttr->pdrSafeRestoreValSmaTx );
|
|
|
|
/* PD_RF_AGC, PD_IF_AGC
|
|
No need to restore; will be restored in SetStandard/SetChannel */
|
|
|
|
/* PD_CVBS, PD_SIF
|
|
No need to restore; will be restored in SetStandard/SetChannel */
|
|
|
|
/* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
|
|
Should be restored via DRX_CTRL_SET_AUD */
|
|
}
|
|
|
|
/* Write magic word to disable pdr reg write */
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A, 0x0000 );
|
|
extAttr->pdrSafeMode = *enable;
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* \brief get configuration of pin-safe mode
|
|
* \param demod instance of demodulator.
|
|
* \param enable boolean indicating whether pin-safe mode is active
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgPdrSafeMode ( pDRXDemodInstance_t demod,
|
|
pBool_t enabled )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t) NULL;
|
|
|
|
if ( enabled == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t) demod->myExtAttr;
|
|
*enabled = extAttr->pdrSafeMode;
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
/**
|
|
* \brief Verifies whether microcode can be loaded.
|
|
* \param demod Demodulator instance.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlValidateUCode (pDRXDemodInstance_t demod)
|
|
{
|
|
u32_t mcDev, mcPatch;
|
|
u16_t verType;
|
|
|
|
/* Check device.
|
|
* Disallow microcode if:
|
|
* - MC has version record AND
|
|
* - device ID in version record is not 0 AND
|
|
* - product ID in version record's device ID does not
|
|
* match DRXJ1 product IDs - 0x393 or 0x394
|
|
*/
|
|
DRX_GET_MCVERTYPE (demod, verType);
|
|
DRX_GET_MCDEV (demod, mcDev);
|
|
DRX_GET_MCPATCH (demod, mcPatch);
|
|
|
|
if (DRX_ISMCVERTYPE (verType))
|
|
{
|
|
if ((mcDev != 0) &&
|
|
(((mcDev >> 16) & 0xFFF) != 0x393) &&
|
|
(((mcDev >> 16) & 0xFFF) != 0x394))
|
|
{
|
|
/* Microcode is marked for another device - error */
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
else if (mcPatch != 0)
|
|
{
|
|
/* Patch not allowed because there is no ROM */
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
/* Everything else: OK */
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/*== END AUXILIARY FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t InitAGC ()
|
|
* \brief Initialize AGC for all standards.
|
|
* \param demod instance of demodulator.
|
|
* \param channel pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
InitAGC ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXJCfgAgc_t pAgcRfSettings = NULL;
|
|
pDRXJCfgAgc_t pAgcIfSettings = NULL;
|
|
u16_t IngainTgtMax = 0;
|
|
u16_t clpDirTo = 0;
|
|
u16_t snsSumMax = 0;
|
|
u16_t clpSumMax = 0;
|
|
u16_t snsDirTo = 0;
|
|
u16_t kiInnergainMin = 0;
|
|
u16_t agcKi = 0;
|
|
u16_t kiMax = 0;
|
|
u16_t ifIaccuHiTgtMin = 0;
|
|
u16_t data = 0;
|
|
u16_t agcKiDgain = 0;
|
|
u16_t kiMin = 0;
|
|
u16_t clpCtrlMode = 0;
|
|
u16_t agcRf = 0;
|
|
u16_t agcIf = 0;
|
|
devAddr = demod->myI2CDevAddr;
|
|
commonAttr = (pDRXCommonAttr_t) demod->myCommonAttr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
switch (extAttr->standard)
|
|
{
|
|
case DRX_STANDARD_8VSB :
|
|
clpSumMax = 1023;
|
|
clpDirTo = (u16_t)(-9);
|
|
snsSumMax = 1023;
|
|
snsDirTo = (u16_t)(-9);
|
|
kiInnergainMin = (u16_t)(-32768);
|
|
kiMax = 0x032C;
|
|
agcKiDgain = 0xC;
|
|
ifIaccuHiTgtMin = 2047;
|
|
kiMin = 0x0117;
|
|
IngainTgtMax = 16383;
|
|
clpCtrlMode = 0;
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_SUM__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_CYCCNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_DIR_WD__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_DIR_STP__A, 1 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_SUM__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_CYCCNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_DIR_WD__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_DIR_STP__A, 1 );
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN__A, 1024 );
|
|
WR16( devAddr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600 );
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT__A, 13200 );
|
|
pAgcIfSettings = &(extAttr->vsbIfAgcCfg);
|
|
pAgcRfSettings = &(extAttr->vsbRfAgcCfg);
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
case DRX_STANDARD_ITU_B:
|
|
IngainTgtMax = 5119;
|
|
clpSumMax = 1023;
|
|
clpDirTo = (u16_t)(-5);
|
|
snsSumMax = 127;
|
|
snsDirTo = (u16_t)(-3);
|
|
kiInnergainMin = 0;
|
|
kiMax = 0x0657;
|
|
ifIaccuHiTgtMin = 2047;
|
|
agcKiDgain = 0x7;
|
|
kiMin = 0x0117;
|
|
clpCtrlMode = 0;
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_SUM__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_CYCCNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_DIR_WD__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_DIR_STP__A, 1 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_SUM__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_CYCCNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_DIR_WD__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_DIR_STP__A, 1 );
|
|
pAgcIfSettings = &(extAttr->qamIfAgcCfg);
|
|
pAgcRfSettings = &(extAttr->qamRfAgcCfg);
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top );
|
|
|
|
RR16( devAddr, SCU_RAM_AGC_KI__A, &agcKi );
|
|
agcKi &= 0xf000;
|
|
WR16( devAddr, SCU_RAM_AGC_KI__A, agcKi );
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_FM:
|
|
clpSumMax = 1023;
|
|
snsSumMax = 1023;
|
|
kiInnergainMin = (u16_t)(-32768);
|
|
ifIaccuHiTgtMin = 2047;
|
|
agcKiDgain = 0x7;
|
|
kiMin = 0x0225;
|
|
kiMax = 0x0547;
|
|
clpDirTo = (u16_t)(-9);
|
|
snsDirTo = (u16_t)(-9);
|
|
IngainTgtMax = 9000;
|
|
clpCtrlMode = 1;
|
|
pAgcIfSettings = &(extAttr->atvIfAgcCfg);
|
|
pAgcRfSettings = &(extAttr->atvRfAgcCfg);
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top );
|
|
break;
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I :
|
|
clpSumMax = 1023;
|
|
snsSumMax = 1023;
|
|
kiInnergainMin = (u16_t)(-32768);
|
|
ifIaccuHiTgtMin = 2047;
|
|
agcKiDgain = 0x7;
|
|
kiMin = 0x0225;
|
|
kiMax = 0x0547;
|
|
clpDirTo = (u16_t)(-9);
|
|
IngainTgtMax = 9000;
|
|
pAgcIfSettings = &(extAttr->atvIfAgcCfg);
|
|
pAgcRfSettings = &(extAttr->atvRfAgcCfg);
|
|
snsDirTo = (u16_t)(-9);
|
|
clpCtrlMode = 1;
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top );
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_L :
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
clpSumMax = 1023;
|
|
snsSumMax = 1023;
|
|
kiInnergainMin = (u16_t)(-32768);
|
|
ifIaccuHiTgtMin = 2047;
|
|
agcKiDgain = 0x7;
|
|
kiMin = 0x0225;
|
|
kiMax = 0x0547;
|
|
clpDirTo = (u16_t)(-9);
|
|
snsDirTo = (u16_t)(-9);
|
|
IngainTgtMax = 9000;
|
|
clpCtrlMode = 1;
|
|
pAgcIfSettings = &(extAttr->atvIfAgcCfg);
|
|
pAgcRfSettings = &(extAttr->atvRfAgcCfg);
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT__A, pAgcIfSettings->top );
|
|
break;
|
|
#endif
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* for new AGC interface */
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcIfSettings->top );
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN__A, pAgcIfSettings->top ); /* Gain fed from inner to outer AGC */
|
|
WR16( devAddr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, IngainTgtMax );
|
|
WR16( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin );
|
|
WR16( devAddr, SCU_RAM_AGC_IF_IACCU_HI__A, 0 ); /* set to pAgcSettings->top before */
|
|
WR16( devAddr, SCU_RAM_AGC_IF_IACCU_LO__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_RF_IACCU_HI__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_RF_IACCU_LO__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_RF_MAX__A, 32767 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin );
|
|
WR16( devAddr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50 );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_CYCLEN__A, 500 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_CYCLEN__A, 500 );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20 );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MIN__A, kiMin );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_MAX__A, kiMax );
|
|
WR16( devAddr, SCU_RAM_AGC_KI_RED__A, 0 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_CYCLEN__A, 500 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8 );
|
|
WR16( devAddr, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo );
|
|
WR16( devAddr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50 );
|
|
WR16( devAddr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode );
|
|
|
|
agcRf = 0x800 + pAgcRfSettings->cutOffCurrent;
|
|
if ( commonAttr->tunerRfAgcPol == TRUE )
|
|
{
|
|
agcRf = 0x87ff - agcRf;
|
|
}
|
|
|
|
agcIf = 0x800;
|
|
if ( commonAttr->tunerIfAgcPol == TRUE )
|
|
{
|
|
agcRf = 0x87ff - agcRf;
|
|
}
|
|
|
|
WR16( devAddr, IQM_AF_AGC_RF__A, agcRf );
|
|
WR16( devAddr, IQM_AF_AGC_IF__A, agcIf );
|
|
|
|
/* Set/restore Ki DGAIN factor */
|
|
RR16( devAddr, SCU_RAM_AGC_KI__A, &data );
|
|
data &= ~SCU_RAM_AGC_KI_DGAIN__M;
|
|
data |= ( agcKiDgain << SCU_RAM_AGC_KI_DGAIN__B );
|
|
WR16( devAddr, SCU_RAM_AGC_KI__A, data );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetFrequency ()
|
|
* \brief Set frequency shift.
|
|
* \param demod instance of demodulator.
|
|
* \param channel pointer to channel data.
|
|
* \param tunerFreqOffset residual frequency from tuner.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetFrequency ( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXFrequency_t tunerFreqOffset
|
|
)
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
DRXFrequency_t samplingFrequency = 0;
|
|
DRXFrequency_t frequencyShift = 0;
|
|
DRXFrequency_t ifFreqActual = 0;
|
|
DRXFrequency_t rfFreqResidual = 0;
|
|
DRXFrequency_t adcFreq = 0;
|
|
DRXFrequency_t intermediateFreq = 0;
|
|
u32_t iqmFsRateOfs = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
Bool_t adcFlip = TRUE;
|
|
Bool_t selectPosImage = FALSE;
|
|
Bool_t rfMirror = FALSE;
|
|
Bool_t tunerMirror = TRUE;
|
|
Bool_t imageToSelect = TRUE;
|
|
DRXFrequency_t fmFrequencyShift = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
rfFreqResidual = -1 * tunerFreqOffset;
|
|
rfMirror = (extAttr->mirror == DRX_MIRROR_YES)?TRUE:FALSE;
|
|
tunerMirror = demod->myCommonAttr->mirrorFreqSpect?FALSE:TRUE;
|
|
/*
|
|
Program frequency shifter
|
|
No need to account for mirroring on RF
|
|
*/
|
|
switch (extAttr->standard)
|
|
{
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
|
|
case DRX_STANDARD_8VSB:
|
|
selectPosImage = TRUE;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
/* After IQM FS sound carrier must appear at 4 Mhz in spect.
|
|
Sound carrier is already 3Mhz above centre frequency due
|
|
to tuner setting so now add an extra shift of 1MHz... */
|
|
fmFrequencyShift = 1000;
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
selectPosImage = FALSE;
|
|
break;
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
intermediateFreq = demod->myCommonAttr->intermediateFreq;
|
|
samplingFrequency = demod->myCommonAttr->sysClockFreq/3;
|
|
if ( tunerMirror == TRUE )
|
|
{
|
|
/* tuner doesn't mirror */
|
|
ifFreqActual = intermediateFreq + rfFreqResidual + fmFrequencyShift;
|
|
} else {
|
|
/* tuner mirrors */
|
|
ifFreqActual = intermediateFreq - rfFreqResidual - fmFrequencyShift;
|
|
}
|
|
if ( ifFreqActual > samplingFrequency / 2)
|
|
{
|
|
/* adc mirrors */
|
|
adcFreq = samplingFrequency - ifFreqActual;
|
|
adcFlip = TRUE;
|
|
} else {
|
|
/* adc doesn't mirror */
|
|
adcFreq = ifFreqActual;
|
|
adcFlip = FALSE;
|
|
}
|
|
|
|
frequencyShift = adcFreq;
|
|
imageToSelect = (Bool_t)(rfMirror ^ tunerMirror ^ adcFlip ^ selectPosImage);
|
|
iqmFsRateOfs = Frac28(frequencyShift,samplingFrequency);
|
|
|
|
if (imageToSelect)
|
|
iqmFsRateOfs = ~iqmFsRateOfs + 1;
|
|
|
|
/* Program frequency shifter with tuner offset compensation */
|
|
/* frequencyShift += tunerFreqOffset; TODO */
|
|
WR32( devAddr, IQM_FS_RATE_OFS_LO__A , iqmFsRateOfs );
|
|
extAttr->iqmFsRateOfs = iqmFsRateOfs;
|
|
extAttr->posImage = (Bool_t)(rfMirror ^ tunerMirror ^ selectPosImage);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetSigStrength()
|
|
* \brief Retrieve signal strength for VSB and QAM.
|
|
* \param demod Pointer to demod instance
|
|
* \param u16-t Pointer to signal strength data; range 0, .. , 100.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigStrength contains valid data.
|
|
* \retval DRX_STS_INVALID_ARG sigStrength is NULL.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
|
|
*/
|
|
#define DRXJ_AGC_TOP 0x2800
|
|
#define DRXJ_AGC_SNS 0x1600
|
|
#define DRXJ_RFAGC_MAX 0x3fff
|
|
#define DRXJ_RFAGC_MIN 0x800
|
|
|
|
static DRXStatus_t
|
|
GetSigStrength( pDRXDemodInstance_t demod,
|
|
pu16_t sigStrength )
|
|
{
|
|
u16_t rfGain = 0;
|
|
u16_t ifGain = 0;
|
|
u16_t ifAgcSns = 0;
|
|
u16_t ifAgcTop = 0;
|
|
u16_t rfAgcMax = 0;
|
|
u16_t rfAgcMin = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
RR16( devAddr, IQM_AF_AGC_IF__A, &ifGain );
|
|
ifGain &= IQM_AF_AGC_IF__M;
|
|
RR16( devAddr, IQM_AF_AGC_RF__A, &rfGain );
|
|
rfGain &= IQM_AF_AGC_RF__M;
|
|
|
|
ifAgcSns = DRXJ_AGC_SNS;
|
|
ifAgcTop = DRXJ_AGC_TOP;
|
|
rfAgcMax = DRXJ_RFAGC_MAX;
|
|
rfAgcMin = DRXJ_RFAGC_MIN;
|
|
|
|
if (ifGain > ifAgcTop)
|
|
{
|
|
if (rfGain > rfAgcMax)
|
|
*sigStrength = 100;
|
|
else if (rfGain > rfAgcMin)
|
|
{
|
|
CHK_ZERO (rfAgcMax - rfAgcMin);
|
|
*sigStrength = 75 + 25 * (rfGain - rfAgcMin) / (rfAgcMax - rfAgcMin);
|
|
}
|
|
else
|
|
*sigStrength = 75;
|
|
}
|
|
else if (ifGain > ifAgcSns)
|
|
{
|
|
CHK_ZERO(ifAgcTop - ifAgcSns);
|
|
*sigStrength = 20 + 55* (ifGain - ifAgcSns)/ (ifAgcTop - ifAgcSns);
|
|
}
|
|
else
|
|
{
|
|
CHK_ZERO (ifAgcSns);
|
|
*sigStrength = (20 * ifGain / ifAgcSns);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetAccPktErr()
|
|
* \brief Retrieve signal strength for VSB and QAM.
|
|
* \param demod Pointer to demod instance
|
|
* \param packetErr Pointer to packet error
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigStrength contains valid data.
|
|
* \retval DRX_STS_INVALID_ARG sigStrength is NULL.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
|
|
*/
|
|
#ifdef DRXJ_SIGNAL_ACCUM_ERR
|
|
static DRXStatus_t
|
|
GetAccPktErr( pDRXDemodInstance_t demod,
|
|
pu16_t packetErr )
|
|
{
|
|
static u16_t pktErr = 0;
|
|
static u16_t lastPktErr = 0;
|
|
u16_t data = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
RR16( devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data );
|
|
if ( extAttr->resetPktErrAcc == TRUE )
|
|
{
|
|
lastPktErr = data;
|
|
pktErr = 0;
|
|
extAttr->resetPktErrAcc = FALSE;
|
|
}
|
|
|
|
if (data < lastPktErr)
|
|
{
|
|
pktErr += 0xffff - lastPktErr;
|
|
pktErr += data;
|
|
}
|
|
else
|
|
{
|
|
pktErr += (data - lastPktErr);
|
|
}
|
|
*packetErr = pktErr;
|
|
lastPktErr = data;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \fn DRXStatus_t ResetAccPktErr()
|
|
* \brief Reset Accumulating packet error count.
|
|
* \param demod Pointer to demod instance
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK.
|
|
* \retval DRX_STS_ERROR Erroneous data.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgResetPktErr( pDRXDemodInstance_t demod )
|
|
{
|
|
#ifdef DRXJ_SIGNAL_ACCUM_ERR
|
|
pDRXJData_t extAttr = NULL;
|
|
u16_t packetError = 0;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
extAttr->resetPktErrAcc = TRUE;
|
|
/* call to reset counter */
|
|
CHK_ERROR (GetAccPktErr (demod, &packetError));
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
#endif
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetSTRFreqOffset()
|
|
* \brief Get symbol rate offset in QAM & 8VSB mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetSTRFreqOffset( pDRXDemodInstance_t demod,
|
|
s32_t *STRFreq
|
|
)
|
|
{
|
|
u32_t symbolFrequencyRatio = 0;
|
|
u32_t symbolNomFrequencyRatio = 0;
|
|
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
standard = extAttr->standard;
|
|
|
|
ARR32( devAddr, IQM_RC_RATE_LO__A, &symbolFrequencyRatio );
|
|
symbolNomFrequencyRatio = extAttr->iqmRcRateOfs;
|
|
|
|
if ( symbolFrequencyRatio > symbolNomFrequencyRatio )
|
|
*STRFreq = -1 * FracTimes1e6( ( symbolFrequencyRatio - symbolNomFrequencyRatio ), (symbolFrequencyRatio + (1 << 23)) );
|
|
else
|
|
*STRFreq = FracTimes1e6( ( symbolNomFrequencyRatio - symbolFrequencyRatio ), (symbolFrequencyRatio + (1 << 23)) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetCTLFreqOffset
|
|
* \brief Get the value of CTLFreq in QAM & ATSC mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetCTLFreqOffset ( pDRXDemodInstance_t demod,
|
|
s32_t *CTLFreq
|
|
)
|
|
{
|
|
DRXFrequency_t samplingFrequency = 0;
|
|
s32_t currentFrequency = 0;
|
|
s32_t nominalFrequency = 0;
|
|
s32_t carrierFrequencyShift = 0;
|
|
s32_t sign = 1;
|
|
u32_t data64Hi = 0;
|
|
u32_t data64Lo = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
samplingFrequency = commonAttr->sysClockFreq/3;
|
|
|
|
/* both registers are sign extended */
|
|
nominalFrequency = extAttr->iqmFsRateOfs;
|
|
ARR32( devAddr, IQM_FS_RATE_LO__A, (pu32_t) ¤tFrequency );
|
|
|
|
if ( extAttr->posImage == TRUE )
|
|
{
|
|
/* negative image */
|
|
carrierFrequencyShift = nominalFrequency - currentFrequency;
|
|
} else {
|
|
/* positive image */
|
|
carrierFrequencyShift = currentFrequency - nominalFrequency;
|
|
}
|
|
|
|
/* carrier Frequency Shift In Hz */
|
|
if (carrierFrequencyShift < 0)
|
|
{
|
|
sign = -1;
|
|
carrierFrequencyShift *= sign;
|
|
}
|
|
|
|
/* *CTLFreq = carrierFrequencyShift * 50.625e6 / (1 << 28); */
|
|
Mult32 ( carrierFrequencyShift, samplingFrequency, &data64Hi, &data64Lo );
|
|
*CTLFreq = (s32_t)((((data64Lo >> 28) & 0xf) | (data64Hi << 4)) * sign);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetAgcRf ()
|
|
* \brief Configure RF AGC
|
|
* \param demod instance of demodulator.
|
|
* \param agcSettings AGC configuration structure
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetAgcRf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings, Bool_t atomic )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXJCfgAgc_t pAgcSettings = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
DRXWriteReg16Func_t ScuWr16 = NULL;
|
|
DRXReadReg16Func_t ScuRr16 = NULL;
|
|
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
if (atomic)
|
|
{
|
|
ScuRr16 = DRXJ_DAP_SCU_AtomicReadReg16;
|
|
ScuWr16 = DRXJ_DAP_SCU_AtomicWriteReg16;
|
|
}
|
|
else
|
|
{
|
|
ScuRr16 = DRXJ_DAP.readReg16Func;
|
|
ScuWr16 = DRXJ_DAP.writeReg16Func;
|
|
}
|
|
|
|
/* Configure AGC only if standard is currently active*/
|
|
if ( ( extAttr->standard == agcSettings->standard ) ||
|
|
( DRXJ_ISQAMSTD( extAttr->standard ) &&
|
|
DRXJ_ISQAMSTD( agcSettings->standard ) ) ||
|
|
( DRXJ_ISATVSTD( extAttr->standard ) &&
|
|
DRXJ_ISATVSTD( agcSettings->standard ) ) )
|
|
{
|
|
u16_t data = 0;
|
|
|
|
switch ( agcSettings->ctrlMode )
|
|
{
|
|
case DRX_AGC_CTRL_AUTO:
|
|
|
|
/* Enable RF AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
|
|
WR16( devAddr, IQM_AF_STDBY__A, data );
|
|
|
|
/* Enable SCU RF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_RF__M;
|
|
if ( extAttr->standard == DRX_STANDARD_8VSB )
|
|
{
|
|
data |= ( 2 << SCU_RAM_AGC_KI_RF__B );
|
|
}
|
|
else if (DRXJ_ISQAMSTD( extAttr->standard ))
|
|
{
|
|
data |= ( 5 << SCU_RAM_AGC_KI_RF__B );
|
|
}
|
|
else
|
|
{
|
|
data |= ( 4 << SCU_RAM_AGC_KI_RF__B );
|
|
}
|
|
|
|
if (commonAttr->tunerRfAgcPol)
|
|
{
|
|
data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
|
|
}
|
|
else
|
|
{
|
|
data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
|
|
}
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
|
|
/* Set speed ( using complementary reduction value ) */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI_RED__A , &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI_RED__A ,
|
|
(~(agcSettings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B)
|
|
& SCU_RAM_AGC_KI_RED_RAGC_RED__M )
|
|
| data, 0 ));
|
|
|
|
if (agcSettings->standard == DRX_STANDARD_8VSB)
|
|
pAgcSettings = &(extAttr->vsbIfAgcCfg);
|
|
else if (DRXJ_ISQAMSTD( agcSettings->standard ))
|
|
pAgcSettings = &(extAttr->qamIfAgcCfg);
|
|
else if (DRXJ_ISATVSTD( agcSettings->standard ))
|
|
pAgcSettings = &(extAttr->atvIfAgcCfg);
|
|
else
|
|
return (DRX_STS_INVALID_ARG);
|
|
|
|
/* Set TOP, only if IF-AGC is in AUTO mode */
|
|
if ( pAgcSettings->ctrlMode == DRX_AGC_CTRL_AUTO)
|
|
{
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
|
|
agcSettings->top, 0 ));
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
|
|
agcSettings->top, 0 ));
|
|
}
|
|
|
|
/* Cut-Off current */
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
|
|
agcSettings->cutOffCurrent, 0 ));
|
|
break;
|
|
case DRX_AGC_CTRL_USER:
|
|
|
|
/* Enable RF AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
/* Disable SCU RF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_RF__M;
|
|
if (commonAttr->tunerRfAgcPol)
|
|
{
|
|
data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
|
|
}
|
|
else
|
|
{
|
|
data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
|
|
}
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
|
|
/* Write value to output pin */
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_RF_IACCU_HI__A, agcSettings->outputLevel, 0 ));
|
|
break;
|
|
case DRX_AGC_CTRL_OFF:
|
|
|
|
/* Disable RF AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
/* Disable SCU RF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_RF__M;
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
} /* switch ( agcsettings->ctrlMode ) */
|
|
}
|
|
|
|
/* Store rf agc settings */
|
|
switch ( agcSettings->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
extAttr->vsbRfAgcCfg = *agcSettings;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
extAttr->qamRfAgcCfg = *agcSettings;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_FM:
|
|
extAttr->atvRfAgcCfg = *agcSettings;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetAgcRf ()
|
|
* \brief get configuration of RF AGC
|
|
* \param demod instance of demodulator.
|
|
* \param agcSettings AGC configuration structure
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
GetAgcRf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* Return stored AGC settings */
|
|
standard = agcSettings->standard;
|
|
switch ( agcSettings->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
*agcSettings = extAttr->vsbRfAgcCfg;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
*agcSettings = extAttr->qamRfAgcCfg;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_FM:
|
|
*agcSettings = extAttr->atvRfAgcCfg;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
agcSettings->standard = standard;
|
|
|
|
/* Get AGC output only if standard is currently active. */
|
|
if ( ( extAttr->standard == agcSettings->standard ) ||
|
|
( DRXJ_ISQAMSTD( extAttr->standard ) &&
|
|
DRXJ_ISQAMSTD( agcSettings->standard ) ) ||
|
|
( DRXJ_ISATVSTD( extAttr->standard ) &&
|
|
DRXJ_ISATVSTD( agcSettings->standard ) ) )
|
|
{
|
|
SARR16( devAddr, SCU_RAM_AGC_RF_IACCU_HI__A,
|
|
&(agcSettings->outputLevel));
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetAgcIf ()
|
|
* \brief Configure If AGC
|
|
* \param demod instance of demodulator.
|
|
* \param agcSettings AGC configuration structure
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetAgcIf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings, Bool_t atomic )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXJCfgAgc_t pAgcSettings = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
DRXWriteReg16Func_t ScuWr16 = NULL;
|
|
DRXReadReg16Func_t ScuRr16 = NULL;
|
|
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
if (atomic)
|
|
{
|
|
ScuRr16 = DRXJ_DAP_SCU_AtomicReadReg16;
|
|
ScuWr16 = DRXJ_DAP_SCU_AtomicWriteReg16;
|
|
}
|
|
else
|
|
{
|
|
ScuRr16 = DRXJ_DAP.readReg16Func;
|
|
ScuWr16 = DRXJ_DAP.writeReg16Func;
|
|
}
|
|
|
|
/* Configure AGC only if standard is currently active*/
|
|
if ( ( extAttr->standard == agcSettings->standard ) ||
|
|
( DRXJ_ISQAMSTD( extAttr->standard ) &&
|
|
DRXJ_ISQAMSTD( agcSettings->standard ) ) ||
|
|
( DRXJ_ISATVSTD( extAttr->standard ) &&
|
|
DRXJ_ISATVSTD( agcSettings->standard ) ) )
|
|
{
|
|
u16_t data = 0;
|
|
|
|
switch ( agcSettings->ctrlMode )
|
|
{
|
|
case DRX_AGC_CTRL_AUTO:
|
|
/* Enable IF AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
/* Enable SCU IF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
|
|
data &= ~SCU_RAM_AGC_KI_IF__M;
|
|
if ( extAttr->standard == DRX_STANDARD_8VSB )
|
|
{
|
|
data |= (3 << SCU_RAM_AGC_KI_IF__B );
|
|
}
|
|
else if (DRXJ_ISQAMSTD( extAttr->standard ))
|
|
{
|
|
data |= (6 << SCU_RAM_AGC_KI_IF__B );
|
|
}
|
|
else
|
|
{
|
|
data |= ( 5 << SCU_RAM_AGC_KI_IF__B );
|
|
}
|
|
|
|
if (commonAttr->tunerIfAgcPol)
|
|
{
|
|
data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
|
|
}
|
|
else
|
|
{
|
|
data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
|
|
}
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
|
|
/* Set speed (using complementary reduction value) */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI_RED__A , &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI_RED__A ,
|
|
(~(agcSettings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B)
|
|
& SCU_RAM_AGC_KI_RED_IAGC_RED__M )
|
|
| data, 0 ));
|
|
|
|
if (agcSettings->standard == DRX_STANDARD_8VSB)
|
|
pAgcSettings = &(extAttr->vsbRfAgcCfg);
|
|
else if (DRXJ_ISQAMSTD( agcSettings->standard ))
|
|
pAgcSettings = &(extAttr->qamRfAgcCfg);
|
|
else if (DRXJ_ISATVSTD( agcSettings->standard ))
|
|
pAgcSettings = &(extAttr->atvRfAgcCfg);
|
|
else
|
|
return (DRX_STS_INVALID_ARG);
|
|
|
|
/* Restore TOP */
|
|
if ( pAgcSettings->ctrlMode == DRX_AGC_CTRL_AUTO)
|
|
{
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
|
|
pAgcSettings->top, 0 ));
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
|
|
pAgcSettings->top, 0 ));
|
|
}
|
|
else
|
|
{
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0 ));
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0 ));
|
|
}
|
|
break;
|
|
|
|
case DRX_AGC_CTRL_USER:
|
|
|
|
/* Enable IF AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
/* Disable SCU IF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
|
|
data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
|
|
if (commonAttr->tunerIfAgcPol)
|
|
{
|
|
data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
|
|
}
|
|
else
|
|
{
|
|
data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
|
|
}
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
|
|
/* Write value to output pin */
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
|
|
agcSettings->outputLevel, 0 ));
|
|
break;
|
|
|
|
case DRX_AGC_CTRL_OFF:
|
|
|
|
/* Disable If AGC DAC */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
/* Disable SCU IF AGC loop */
|
|
CHK_ERROR((*ScuRr16)( devAddr, SCU_RAM_AGC_KI__A, &data, 0 ));
|
|
data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
|
|
data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
|
|
CHK_ERROR((*ScuWr16)( devAddr, SCU_RAM_AGC_KI__A, data, 0 ));
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
} /* switch ( agcsettings->ctrlMode ) */
|
|
|
|
/* always set the top to support configurations without if-loop */
|
|
CHK_ERROR((*ScuWr16)( devAddr,
|
|
SCU_RAM_AGC_INGAIN_TGT_MIN__A,
|
|
agcSettings->top,
|
|
0 ) );
|
|
}
|
|
|
|
/* Store if agc settings */
|
|
switch ( agcSettings->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
extAttr->vsbIfAgcCfg = *agcSettings;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
extAttr->qamIfAgcCfg = *agcSettings;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_FM:
|
|
extAttr->atvIfAgcCfg = *agcSettings;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetAgcIf ()
|
|
* \brief get configuration of If AGC
|
|
* \param demod instance of demodulator.
|
|
* \param agcSettings AGC configuration structure
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
GetAgcIf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* Return stored ATV AGC settings */
|
|
standard = agcSettings->standard;
|
|
switch ( agcSettings->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
*agcSettings = extAttr->vsbIfAgcCfg;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
*agcSettings = extAttr->qamIfAgcCfg;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_FM:
|
|
*agcSettings = extAttr->atvIfAgcCfg;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
agcSettings->standard = standard;
|
|
|
|
/* Get AGC output only if standard is currently active */
|
|
if ( ( extAttr->standard == agcSettings->standard ) ||
|
|
( DRXJ_ISQAMSTD( extAttr->standard ) &&
|
|
DRXJ_ISQAMSTD( agcSettings->standard ) ) ||
|
|
( DRXJ_ISATVSTD( extAttr->standard ) &&
|
|
DRXJ_ISATVSTD( agcSettings->standard ) ) )
|
|
{
|
|
/* read output level */
|
|
SARR16( devAddr, SCU_RAM_AGC_IF_IACCU_HI__A,
|
|
&(agcSettings->outputLevel) );
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetIqmAf ()
|
|
* \brief Configure IQM AF registers
|
|
* \param demod instance of demodulator.
|
|
* \param active
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetIqmAf ( pDRXDemodInstance_t demod, Bool_t active )
|
|
{
|
|
u16_t data = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Configure IQM */
|
|
RR16( devAddr, IQM_AF_STDBY__A , &data );
|
|
if( !active )
|
|
{
|
|
data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
|
|
& (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
|
|
);
|
|
}
|
|
else /* active */
|
|
{
|
|
data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
|
|
| IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE
|
|
);
|
|
}
|
|
WR16( devAddr, IQM_AF_STDBY__A , data );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== 8VSB DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
|
|
/**
|
|
* \fn DRXStatus_t PowerDownVSB ()
|
|
* \brief Powr down QAM related blocks.
|
|
* \param demod instance of demodulator.
|
|
* \param channel pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
PowerDownVSB( pDRXDemodInstance_t demod, Bool_t primary )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* *parameter */ NULL,
|
|
/* *result */ NULL };
|
|
u16_t cmdResult = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXCfgMPEGOutput_t cfgMPEGOutput;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod->myExtAttr;
|
|
/*
|
|
STOP demodulator
|
|
reset of FEC and VSB HW
|
|
*/
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_STOP;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
/* stop all comm_exec */
|
|
WR16( devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP );
|
|
WR16( devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP );
|
|
if (primary == TRUE)
|
|
{
|
|
WR16( devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP );
|
|
CHK_ERROR( SetIqmAf( demod, FALSE ) );
|
|
}
|
|
else
|
|
{
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
}
|
|
|
|
cfgMPEGOutput.enableMPEGOutput = FALSE;
|
|
CHK_ERROR( CtrlSetCfgMPEGOutput( demod, &cfgMPEGOutput) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t SetVSBLeakNGain ()
|
|
* \brief Set ATSC demod.
|
|
* \param demod instance of demodulator.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetVSBLeakNGain ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
const u8_t vsb_ffe_leak_gain_ram0[]= {
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO1 */
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO2 */
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO3 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO4 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO5 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO6 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO7 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO8 */
|
|
DRXJ_16TO8( 0xf ), /* FFETRAINLKRATIO9 */
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO10 */
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO11 */
|
|
DRXJ_16TO8( 0x8 ), /* FFETRAINLKRATIO12 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO1 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO2 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO3 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO4 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO5 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO6 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO7 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO8 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1TRAINLKRATIO9 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO10 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO11 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1TRAINLKRATIO12 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO1 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO2 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO3 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO4 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO5 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO6 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO7 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO8 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA1DATALKRATIO9 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO10 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO11 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA1DATALKRATIO12 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO1 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO2 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO3 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO4 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO5 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO6 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO7 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO8 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2TRAINLKRATIO9 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO10 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO11 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2TRAINLKRATIO12 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO1 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO2 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO3 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO4 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO5 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO6 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO7 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO8 */
|
|
DRXJ_16TO8( 0x20 ), /* FFERCA2DATALKRATIO9 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO10 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO11 */
|
|
DRXJ_16TO8( 0x10 ), /* FFERCA2DATALKRATIO12 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO1 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO2 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO3 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO4 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO5 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO6 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO7 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO8 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1TRAINLKRATIO9 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO10 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO11 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1TRAINLKRATIO12 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO1 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO2 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO3 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO4 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO5 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO6 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO7 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO8 */
|
|
DRXJ_16TO8( 0x0e ), /* FFEDDM1DATALKRATIO9 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO10 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO11 */
|
|
DRXJ_16TO8( 0x07 ), /* FFEDDM1DATALKRATIO12 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO1 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO2 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO3 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO4 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO5 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO6 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO7 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO8 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2TRAINLKRATIO9 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO10 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO11 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2TRAINLKRATIO12 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO1 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO2 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO3 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO4 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO5 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO6 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO7 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO8 */
|
|
DRXJ_16TO8( 0x0c ), /* FFEDDM2DATALKRATIO9 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO10 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO11 */
|
|
DRXJ_16TO8( 0x06 ), /* FFEDDM2DATALKRATIO12 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN1 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN2 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN3 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN4 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN5 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN6 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN7 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN8 */
|
|
DRXJ_16TO8( 0x4040 ), /* FIRTRAINGAIN9 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN10 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN11 */
|
|
DRXJ_16TO8( 0x2020 ), /* FIRTRAINGAIN12 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN1 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN2 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN3 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA1GAIN4 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA1GAIN5 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA1GAIN6 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA1GAIN7 */
|
|
DRXJ_16TO8( 0x1010 ) /* FIRRCA1GAIN8 */
|
|
};
|
|
|
|
const u8_t vsb_ffe_leak_gain_ram1[]= {
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA1GAIN9 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN10 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN11 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA1GAIN12 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN1 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN2 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN3 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN4 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN5 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN6 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN7 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN8 */
|
|
DRXJ_16TO8( 0x1010 ), /* FIRRCA2GAIN9 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN10 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN11 */
|
|
DRXJ_16TO8( 0x0808 ), /* FIRRCA2GAIN12 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN1 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN2 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN3 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN4 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN5 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN6 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN7 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN8 */
|
|
DRXJ_16TO8( 0x0606 ), /* FIRDDM1GAIN9 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN10 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN11 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM1GAIN12 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN1 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN2 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN3 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN4 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN5 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN6 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN7 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN8 */
|
|
DRXJ_16TO8( 0x0505 ), /* FIRDDM2GAIN9 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN10 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN11 */
|
|
DRXJ_16TO8( 0x0303 ), /* FIRDDM2GAIN12 */
|
|
DRXJ_16TO8( 0x001f ), /* DFETRAINLKRATIO */
|
|
DRXJ_16TO8( 0x01ff ), /* DFERCA1TRAINLKRATIO */
|
|
DRXJ_16TO8( 0x01ff ), /* DFERCA1DATALKRATIO */
|
|
DRXJ_16TO8( 0x004f ), /* DFERCA2TRAINLKRATIO */
|
|
DRXJ_16TO8( 0x004f ), /* DFERCA2DATALKRATIO */
|
|
DRXJ_16TO8( 0x01ff ), /* DFEDDM1TRAINLKRATIO */
|
|
DRXJ_16TO8( 0x01ff ), /* DFEDDM1DATALKRATIO */
|
|
DRXJ_16TO8( 0x0352 ), /* DFEDDM2TRAINLKRATIO */
|
|
DRXJ_16TO8( 0x0352 ), /* DFEDDM2DATALKRATIO */
|
|
DRXJ_16TO8( 0x0000 ), /* DFETRAINGAIN */
|
|
DRXJ_16TO8( 0x2020 ), /* DFERCA1GAIN */
|
|
DRXJ_16TO8( 0x1010 ), /* DFERCA2GAIN */
|
|
DRXJ_16TO8( 0x1818 ), /* DFEDDM1GAIN */
|
|
DRXJ_16TO8( 0x1212 ) /* DFEDDM2GAIN */
|
|
};
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
WRB ( devAddr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A,
|
|
sizeof(vsb_ffe_leak_gain_ram0), ((pu8_t)vsb_ffe_leak_gain_ram0) );
|
|
WRB ( devAddr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A,
|
|
sizeof(vsb_ffe_leak_gain_ram1), ((pu8_t)vsb_ffe_leak_gain_ram1) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetVSB()
|
|
* \brief Set 8VSB demod.
|
|
* \param demod instance of demodulator.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SetVSB ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
u16_t cmdResult = 0;
|
|
u16_t cmdParam = 0;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
DRXJSCUCmd_t cmdSCU;
|
|
pDRXJData_t extAttr = NULL;
|
|
const u8_t vsb_taps_re[]= {
|
|
DRXJ_16TO8( -2 ), /* re0 */
|
|
DRXJ_16TO8( 4 ), /* re1 */
|
|
DRXJ_16TO8( 1 ), /* re2 */
|
|
DRXJ_16TO8( -4 ), /* re3 */
|
|
DRXJ_16TO8( 1 ), /* re4 */
|
|
DRXJ_16TO8( 4 ), /* re5 */
|
|
DRXJ_16TO8( -3 ), /* re6 */
|
|
DRXJ_16TO8( -3 ), /* re7 */
|
|
DRXJ_16TO8( 6 ), /* re8 */
|
|
DRXJ_16TO8( 1 ), /* re9 */
|
|
DRXJ_16TO8( -9 ), /* re10 */
|
|
DRXJ_16TO8( 3 ), /* re11 */
|
|
DRXJ_16TO8( 12 ), /* re12 */
|
|
DRXJ_16TO8( -9 ), /* re13 */
|
|
DRXJ_16TO8( -15 ), /* re14 */
|
|
DRXJ_16TO8( 17 ), /* re15 */
|
|
DRXJ_16TO8( 19 ), /* re16 */
|
|
DRXJ_16TO8( -29 ), /* re17 */
|
|
DRXJ_16TO8( -22 ), /* re18 */
|
|
DRXJ_16TO8( 45 ), /* re19 */
|
|
DRXJ_16TO8( 25 ), /* re20 */
|
|
DRXJ_16TO8( -70 ), /* re21 */
|
|
DRXJ_16TO8( -28 ), /* re22 */
|
|
DRXJ_16TO8( 111 ), /* re23 */
|
|
DRXJ_16TO8( 30 ), /* re24 */
|
|
DRXJ_16TO8( -201 ), /* re25 */
|
|
DRXJ_16TO8( -31 ), /* re26 */
|
|
DRXJ_16TO8( 629 ) /* re27 */
|
|
};
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* stop all comm_exec */
|
|
WR16( devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP );
|
|
WR16( devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
|
|
/* reset demodulator */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_RESET;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
WR16( devAddr, IQM_AF_DCF_BYPASS__A, 1 );
|
|
WR16( devAddr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB );
|
|
WR16( devAddr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB );
|
|
extAttr->iqmRcRateOfs = 0x00AD0D79;
|
|
WR32( devAddr, IQM_RC_RATE_OFS_LO__A, extAttr->iqmRcRateOfs );
|
|
WR16( devAddr, VSB_TOP_CFAGC_GAINSHIFT__A, 4);
|
|
WR16( devAddr, VSB_TOP_CYGN1TRK__A, 1);
|
|
|
|
WR16( devAddr, IQM_RC_CROUT_ENA__A, 1 );
|
|
WR16( devAddr, IQM_RC_STRETCH__A, 28 );
|
|
WR16( devAddr, IQM_RT_ACTIVE__A, 0 );
|
|
WR16( devAddr, IQM_CF_SYMMETRIC__A, 0 );
|
|
WR16( devAddr, IQM_CF_MIDTAP__A, 3 );
|
|
WR16( devAddr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M );
|
|
WR16( devAddr, IQM_CF_SCALE__A, 1393 );
|
|
WR16( devAddr, IQM_CF_SCALE_SH__A, 0 );
|
|
WR16( devAddr, IQM_CF_POW_MEAS_LEN__A, 1);
|
|
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((pu8_t)vsb_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((pu8_t)vsb_taps_re) );
|
|
|
|
WR16( devAddr, VSB_TOP_BNTHRESH__A, 330 ); /* set higher threshold */
|
|
WR16( devAddr, VSB_TOP_CLPLASTNUM__A, 90 ); /* burst detection on */
|
|
WR16( devAddr, VSB_TOP_SNRTH_RCA1__A, 0x0042 ); /* drop thresholds by 1 dB */
|
|
WR16( devAddr, VSB_TOP_SNRTH_RCA2__A, 0x0053 ); /* drop thresholds by 2 dB */
|
|
WR16( devAddr, VSB_TOP_EQCTRL__A, 0x1 ); /* cma on */
|
|
WR16( devAddr, SCU_RAM_GPIO__A, 0 ); /* GPIO */
|
|
|
|
/* Initialize the FEC Subsystem */
|
|
WR16( devAddr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D );
|
|
{
|
|
u16_t fecOcSncMode = 0;
|
|
RR16( devAddr, FEC_OC_SNC_MODE__A, &fecOcSncMode );
|
|
/* output data even when not locked */
|
|
WR16( devAddr, FEC_OC_SNC_MODE__A, fecOcSncMode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M );
|
|
}
|
|
|
|
/* set clip */
|
|
WR16( devAddr, IQM_AF_CLP_LEN__A, 0);
|
|
WR16( devAddr, IQM_AF_CLP_TH__A, 470);
|
|
WR16( devAddr, IQM_AF_SNS_LEN__A, 0);
|
|
WR16( devAddr, VSB_TOP_SNRTH_PT__A, 0xD4 );
|
|
/* no transparent, no A&C framing; parity is set in mpegoutput*/
|
|
{
|
|
u16_t fecOcRegMode = 0;
|
|
RR16 ( devAddr, FEC_OC_MODE__A , &fecOcRegMode );
|
|
WR16( devAddr, FEC_OC_MODE__A, fecOcRegMode &
|
|
(~(FEC_OC_MODE_TRANSPARENT__M
|
|
| FEC_OC_MODE_CLEAR__M
|
|
| FEC_OC_MODE_RETAIN_FRAMING__M)
|
|
) );
|
|
}
|
|
|
|
WR16( devAddr, FEC_DI_TIMEOUT_LO__A, 0 ); /* timeout counter for restarting */
|
|
WR16( devAddr, FEC_DI_TIMEOUT_HI__A, 3 );
|
|
WR16( devAddr, FEC_RS_MODE__A, 0 ); /* bypass disabled */
|
|
/* initialize RS packet error measurement parameters */
|
|
WR16( devAddr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD );
|
|
WR16( devAddr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE );
|
|
|
|
/* init measurement period of MER/SER */
|
|
WR16( devAddr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD );
|
|
WR32( devAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0 );
|
|
WR16( devAddr, SCU_RAM_FEC_MEAS_COUNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0 );
|
|
|
|
WR16( devAddr, VSB_TOP_CKGN1TRK__A, 128 );
|
|
/* B-Input to ADC, PGA+filter in standby */
|
|
if ( extAttr->hasLNA == FALSE )
|
|
{
|
|
WR16( devAddr, IQM_AF_AMUX__A, 0x02);
|
|
};
|
|
|
|
/* turn on IQMAF. It has to be in front of setAgc**() */
|
|
CHK_ERROR( SetIqmAf( demod, TRUE ) );
|
|
CHK_ERROR(ADCSynchronization (demod));
|
|
|
|
CHK_ERROR( InitAGC( demod ) );
|
|
CHK_ERROR( SetAgcIf( demod, &(extAttr->vsbIfAgcCfg), FALSE ) );
|
|
CHK_ERROR( SetAgcRf( demod, &(extAttr->vsbRfAgcCfg), FALSE ) );
|
|
{
|
|
/* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
|
|
of only the gain */
|
|
DRXJCfgAfeGain_t vsbPgaCfg = { DRX_STANDARD_8VSB, 0 };
|
|
|
|
vsbPgaCfg.gain = extAttr->vsbPgaCfg;
|
|
CHK_ERROR( CtrlSetCfgAfeGain( demod, &vsbPgaCfg ) );
|
|
}
|
|
CHK_ERROR( CtrlSetCfgPreSaw( demod, &(extAttr->vsbPreSawCfg)) );
|
|
|
|
/* Mpeg output has to be in front of FEC active */
|
|
CHK_ERROR ( SetMPEGTEIHandling ( demod ));
|
|
CHK_ERROR ( BitReverseMPEGOutput( demod ) );
|
|
CHK_ERROR ( SetMPEGStartWidth ( demod ) );
|
|
{
|
|
/* TODO: move to setStandard after hardware reset value problem is solved */
|
|
/* Configure initial MPEG output */
|
|
DRXCfgMPEGOutput_t cfgMPEGOutput;
|
|
cfgMPEGOutput.enableMPEGOutput = TRUE;
|
|
cfgMPEGOutput.insertRSByte = commonAttr->mpegCfg.insertRSByte;
|
|
cfgMPEGOutput.enableParallel = commonAttr->mpegCfg.enableParallel;
|
|
cfgMPEGOutput.invertDATA = commonAttr->mpegCfg.invertDATA;
|
|
cfgMPEGOutput.invertERR = commonAttr->mpegCfg.invertERR;
|
|
cfgMPEGOutput.invertSTR = commonAttr->mpegCfg.invertSTR;
|
|
cfgMPEGOutput.invertVAL = commonAttr->mpegCfg.invertVAL;
|
|
cfgMPEGOutput.invertCLK = commonAttr->mpegCfg.invertCLK;
|
|
cfgMPEGOutput.staticCLK = commonAttr->mpegCfg.staticCLK;
|
|
cfgMPEGOutput.bitrate = commonAttr->mpegCfg.bitrate;
|
|
CHK_ERROR( CtrlSetCfgMPEGOutput( demod, &cfgMPEGOutput) );
|
|
}
|
|
|
|
/* TBD: what parameters should be set */
|
|
cmdParam = 0x00; /* Default mode AGC on, etc */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
|
|
cmdSCU.parameterLen = 1;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = &cmdParam;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
WR16(devAddr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004 );
|
|
WR16(devAddr, VSB_TOP_SNRTH_PT__A, 0x00D2 );
|
|
WR16(devAddr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE
|
|
|VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M );
|
|
WR16(devAddr, VSB_TOP_BEDETCTRL__A, 0x142 );
|
|
WR16(devAddr, VSB_TOP_LBAGCREFLVL__A, 640 );
|
|
WR16(devAddr, VSB_TOP_CYGN1ACQ__A, 4 );
|
|
WR16(devAddr, VSB_TOP_CYGN1TRK__A, 2 );
|
|
WR16(devAddr, VSB_TOP_CYGN2TRK__A, 3 );
|
|
|
|
/* start demodulator */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_START;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE );
|
|
WR16(devAddr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE );
|
|
WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetVSBPostRSPckErr(pI2CDeviceAddr_t devAddr, pu16_t PckErrs)
|
|
* \brief Get the values of packet error in 8VSB mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetVSBPostRSPckErr(pI2CDeviceAddr_t devAddr, pu16_t pckErrs)
|
|
{
|
|
u16_t data = 0;
|
|
u16_t period = 0;
|
|
u16_t prescale = 0;
|
|
u16_t packetErrorsMant = 0;
|
|
u16_t packetErrorsExp = 0;
|
|
|
|
RR16(devAddr, FEC_RS_NR_FAILURES__A, &data );
|
|
packetErrorsMant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
|
|
packetErrorsExp = (data & FEC_RS_NR_FAILURES_EXP__M)
|
|
>> FEC_RS_NR_FAILURES_EXP__B;
|
|
period = FEC_RS_MEASUREMENT_PERIOD;
|
|
prescale = FEC_RS_MEASUREMENT_PRESCALE;
|
|
/* packet error rate = (error packet number) per second */
|
|
/* 77.3 us is time for per packet */
|
|
CHK_ZERO (period * prescale);
|
|
*pckErrs = (u16_t)FracTimes1e6(packetErrorsMant * (1 << packetErrorsExp),
|
|
(period * prescale * 77));
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetVSBBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
|
|
* \brief Get the values of ber in VSB mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetVSBpostViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
|
|
{
|
|
u16_t data = 0;
|
|
u16_t period = 0;
|
|
u16_t prescale = 0;
|
|
u16_t bitErrorsMant = 0;
|
|
u16_t bitErrorsExp = 0;
|
|
|
|
RR16 ( devAddr, FEC_RS_NR_BIT_ERRORS__A, &data );
|
|
period = FEC_RS_MEASUREMENT_PERIOD;
|
|
prescale = FEC_RS_MEASUREMENT_PRESCALE;
|
|
|
|
bitErrorsMant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
|
|
bitErrorsExp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
|
|
>> FEC_RS_NR_BIT_ERRORS_EXP__B;
|
|
|
|
if ( ((bitErrorsMant << bitErrorsExp) >> 3) > 68700)
|
|
*ber = 26570;
|
|
else
|
|
{
|
|
CHK_ZERO (period * prescale);
|
|
*ber = FracTimes1e6(bitErrorsMant << ((bitErrorsExp > 2)? (bitErrorsExp - 3):bitErrorsExp),
|
|
period * prescale * 207 * ((bitErrorsExp > 2)?1:8) );
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetVSBpreViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
|
|
* \brief Get the values of ber in VSB mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetVSBpreViterbiBer(pI2CDeviceAddr_t devAddr, pu32_t ber)
|
|
{
|
|
u16_t data = 0;
|
|
|
|
RR16 ( devAddr, VSB_TOP_NR_SYM_ERRS__A, &data );
|
|
*ber = FracTimes1e6( data, VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static short GetVSBSymbErr(pI2CDeviceAddr_t devAddr, pu32_t ber)
|
|
* \brief Get the values of ber in VSB mode
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetVSBSymbErr(pI2CDeviceAddr_t devAddr, pu32_t ser)
|
|
{
|
|
u16_t data = 0;
|
|
u16_t period = 0;
|
|
u16_t prescale = 0;
|
|
u16_t symbErrorsMant = 0;
|
|
u16_t symbErrorsExp = 0;
|
|
|
|
RR16 ( devAddr, FEC_RS_NR_SYMBOL_ERRORS__A, &data );
|
|
period = FEC_RS_MEASUREMENT_PERIOD;
|
|
prescale = FEC_RS_MEASUREMENT_PRESCALE;
|
|
|
|
symbErrorsMant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
|
|
symbErrorsExp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
|
|
>> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
|
|
|
|
CHK_ZERO (period * prescale);
|
|
*ser = (u32_t)FracTimes1e6((symbErrorsMant << symbErrorsExp) * 1000,
|
|
(period * prescale * 77318));
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn static DRXStatus_t GetVSBMER(pI2CDeviceAddr_t devAddr, pu16_t mer)
|
|
* \brief Get the values of MER
|
|
* \return Error code
|
|
*/
|
|
static DRXStatus_t
|
|
GetVSBMER (pI2CDeviceAddr_t devAddr, pu16_t mer)
|
|
{
|
|
u16_t dataHi = 0;
|
|
|
|
RR16( devAddr, VSB_TOP_ERR_ENERGY_H__A, &dataHi );
|
|
*mer = (u16_t)(Log10Times100( 21504 ) - Log10Times100( (dataHi << 6) / 52 ));
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetVSBConstel()
|
|
* \brief Retreive a VSB constellation point via I2C.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param complexNr Pointer to the structure in which to store the
|
|
constellation point.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetVSBConstel( pDRXDemodInstance_t demod,
|
|
pDRXComplex_t complexNr )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL; /**< device address */
|
|
u16_t vsbTopCommMb = 0; /**< VSB SL MB configuration */
|
|
u16_t vsbTopCommMbInit = 0; /**< VSB SL MB intial configuration */
|
|
u16_t re = 0; /**< constellation Re part */
|
|
u32_t data = 0;
|
|
|
|
/* read device info */
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* TODO: */
|
|
/* Monitor bus grabbing is an open external interface issue */
|
|
/* Needs to be checked when external interface PG is updated */
|
|
|
|
/* Configure MB (Monitor bus) */
|
|
RR16( devAddr, VSB_TOP_COMM_MB__A, &vsbTopCommMbInit );
|
|
/* set observe flag & MB mux */
|
|
vsbTopCommMb = (vsbTopCommMbInit |
|
|
VSB_TOP_COMM_MB_OBS_OBS_ON |
|
|
VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2 );
|
|
WR16( devAddr, VSB_TOP_COMM_MB__A, vsbTopCommMb );
|
|
|
|
/* Enable MB grabber in the FEC OC */
|
|
WR16( devAddr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M );
|
|
|
|
/* Disable MB grabber in the FEC OC */
|
|
WR16( devAddr, FEC_OC_OCR_MODE__A, 0x0 );
|
|
|
|
/* read data */
|
|
RR32( devAddr, FEC_OC_OCR_GRAB_RD1__A, &data );
|
|
re = (u16_t)(((data >> 10) & 0x300 ) | ((data >> 2) & 0xff));
|
|
if (re & 0x0200)
|
|
{
|
|
re |= 0xfc00;
|
|
}
|
|
complexNr->re = re;
|
|
complexNr->im = 0;
|
|
|
|
/* Restore MB (Monitor bus) */
|
|
WR16( devAddr, VSB_TOP_COMM_MB__A, vsbTopCommMbInit );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*============================================================================*/
|
|
/*== END 8VSB DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== QAM DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t PowerDownQAM ()
|
|
* \brief Powr down QAM related blocks.
|
|
* \param demod instance of demodulator.
|
|
* \param channel pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
PowerDownQAM( pDRXDemodInstance_t demod, Bool_t primary )
|
|
{
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* *parameter */ NULL,
|
|
/* *result */ NULL };
|
|
u16_t cmdResult = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXCfgMPEGOutput_t cfgMPEGOutput;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/*
|
|
STOP demodulator
|
|
resets IQM, QAM and FEC HW blocks
|
|
*/
|
|
/* stop all comm_exec */
|
|
WR16( devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
|
|
WR16( devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
|
|
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_STOP;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
if (primary == TRUE)
|
|
{
|
|
WR16( devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP );
|
|
CHK_ERROR( SetIqmAf( demod, FALSE ) );
|
|
}
|
|
else
|
|
{
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
}
|
|
|
|
cfgMPEGOutput.enableMPEGOutput = FALSE;
|
|
CHK_ERROR( CtrlSetCfgMPEGOutput( demod, &cfgMPEGOutput) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAMMeasurement ()
|
|
* \brief Setup of the QAM Measuremnt intervals for signal quality
|
|
* \param demod instance of demod.
|
|
* \param constellation current constellation.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* NOTE:
|
|
* Take into account that for certain settings the errorcounters can overflow.
|
|
* The implementation does not check this.
|
|
*
|
|
* TODO: overriding the extAttr->fecBitsDesired by constellation dependent
|
|
* constants to get a measurement period of approx. 1 sec. Remove fecBitsDesired
|
|
* field ?
|
|
*
|
|
*/
|
|
#ifndef DRXJ_VSB_ONLY
|
|
static DRXStatus_t
|
|
SetQAMMeasurement ( pDRXDemodInstance_t demod,
|
|
DRXConstellation_t constellation,
|
|
u32_t symbolRate )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL; /* device address for I2C writes */
|
|
pDRXJData_t extAttr = NULL; /* Global data container for DRXJ specif data */
|
|
u32_t fecBitsDesired = 0; /* BER accounting period */
|
|
u16_t fecRsPlen = 0; /* defines RS BER measurement period */
|
|
u16_t fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
|
|
u32_t fecRsPeriod = 0; /* Value for corresponding I2C register */
|
|
u32_t fecRsBitCnt = 0; /* Actual precise amount of bits */
|
|
u32_t fecOcSncFailPeriod = 0; /* Value for corresponding I2C register */
|
|
u32_t qamVdPeriod = 0; /* Value for corresponding I2C register */
|
|
u32_t qamVdBitCnt = 0; /* Actual precise amount of bits */
|
|
u16_t fecVdPlen = 0; /* no of trellis symbols: VD SER measur period */
|
|
u16_t qamVdPrescale = 0; /* Viterbi Measurement Prescale */
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
fecBitsDesired = extAttr->fecBitsDesired;
|
|
fecRsPrescale = extAttr->fecRsPrescale;
|
|
|
|
switch ( constellation ) {
|
|
case DRX_CONSTELLATION_QAM16:
|
|
fecBitsDesired = 4 * symbolRate;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
fecBitsDesired = 5 * symbolRate;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
fecBitsDesired = 6 * symbolRate;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
fecBitsDesired = 7 * symbolRate;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
fecBitsDesired = 8 * symbolRate;
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* Parameters for Reed-Solomon Decoder */
|
|
/* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
|
|
/* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
|
|
/* result is within 32 bit arithmetic -> */
|
|
/* no need for mult or frac functions */
|
|
|
|
/* TODO: use constant instead of calculation and remove the fecRsPlen in extAttr */
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
fecRsPlen = 204 * 8;
|
|
break;
|
|
case DRX_STANDARD_ITU_B:
|
|
fecRsPlen = 128 * 7;
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr->fecRsPlen = fecRsPlen; /* for getSigQual */
|
|
fecRsBitCnt = fecRsPrescale * fecRsPlen; /* temp storage */
|
|
CHK_ZERO (fecRsBitCnt);
|
|
fecRsPeriod = fecBitsDesired / fecRsBitCnt + 1; /* ceil */
|
|
if (extAttr->standard != DRX_STANDARD_ITU_B)
|
|
fecOcSncFailPeriod = fecRsPeriod;
|
|
|
|
/* limit to max 16 bit value (I2C register width) if needed */
|
|
if ( fecRsPeriod > 0xFFFF )
|
|
fecRsPeriod = 0xFFFF;
|
|
|
|
/* write corresponding registers */
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_C:
|
|
break;
|
|
case DRX_STANDARD_ITU_B:
|
|
switch ( constellation ) {
|
|
case DRX_CONSTELLATION_QAM64:
|
|
fecRsPeriod = 31581;
|
|
fecOcSncFailPeriod = 17932;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
fecRsPeriod = 45446;
|
|
fecOcSncFailPeriod = 25805;
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
WR16 ( devAddr, FEC_OC_SNC_FAIL_PERIOD__A , ( u16_t ) fecOcSncFailPeriod );
|
|
WR16 ( devAddr, FEC_RS_MEASUREMENT_PERIOD__A , ( u16_t ) fecRsPeriod );
|
|
WR16 ( devAddr, FEC_RS_MEASUREMENT_PRESCALE__A , fecRsPrescale );
|
|
extAttr->fecRsPeriod = (u16_t) fecRsPeriod;
|
|
extAttr->fecRsPrescale = fecRsPrescale;
|
|
WR32( devAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0 );
|
|
WR16( devAddr, SCU_RAM_FEC_MEAS_COUNT__A, 0 );
|
|
WR16( devAddr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0 );
|
|
|
|
if (extAttr->standard == DRX_STANDARD_ITU_B)
|
|
{
|
|
/* Parameters for Viterbi Decoder */
|
|
/* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
|
|
/* (qamvd_prescale*plen*(qam_constellation+1))) */
|
|
/* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
|
|
/* result is within 32 bit arithmetic -> */
|
|
/* no need for mult or frac functions */
|
|
|
|
/* a(8 bit) * b(8 bit) = 16 bit result => Mult32 not needed */
|
|
fecVdPlen = extAttr->fecVdPlen;
|
|
qamVdPrescale = extAttr->qamVdPrescale;
|
|
qamVdBitCnt = qamVdPrescale * fecVdPlen; /* temp storage */
|
|
|
|
switch ( constellation ) {
|
|
case DRX_CONSTELLATION_QAM64:
|
|
/* a(16 bit) * b(4 bit) = 20 bit result => Mult32 not needed */
|
|
qamVdPeriod = qamVdBitCnt * ( QAM_TOP_CONSTELLATION_QAM64 + 1 )
|
|
* ( QAM_TOP_CONSTELLATION_QAM64 + 1 );
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
/* a(16 bit) * b(5 bit) = 21 bit result => Mult32 not needed */
|
|
qamVdPeriod = qamVdBitCnt * ( QAM_TOP_CONSTELLATION_QAM256 + 1 )
|
|
* ( QAM_TOP_CONSTELLATION_QAM256 + 1 );
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
CHK_ZERO (qamVdPeriod);
|
|
qamVdPeriod = fecBitsDesired / qamVdPeriod;
|
|
/* limit to max 16 bit value (I2C register width) if needed */
|
|
if ( qamVdPeriod > 0xFFFF )
|
|
qamVdPeriod = 0xFFFF;
|
|
|
|
/* a(16 bit) * b(16 bit) = 32 bit result => Mult32 not needed */
|
|
qamVdBitCnt *= qamVdPeriod;
|
|
|
|
WR16 ( devAddr, QAM_VD_MEASUREMENT_PERIOD__A , ( u16_t ) qamVdPeriod );
|
|
WR16 ( devAddr, QAM_VD_MEASUREMENT_PRESCALE__A , qamVdPrescale );
|
|
extAttr->qamVdPeriod = (u16_t) qamVdPeriod;
|
|
extAttr->qamVdPrescale = qamVdPrescale;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM16 ()
|
|
* \brief QAM16 specific setup
|
|
* \param demod instance of demod.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM16 ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
|
|
const u8_t qamDqQualFun[]= {
|
|
DRXJ_16TO8( 2 ), /* fun0 */
|
|
DRXJ_16TO8( 2 ), /* fun1 */
|
|
DRXJ_16TO8( 2 ), /* fun2 */
|
|
DRXJ_16TO8( 2 ), /* fun3 */
|
|
DRXJ_16TO8( 3 ), /* fun4 */
|
|
DRXJ_16TO8( 3 ), /* fun5 */
|
|
};
|
|
const u8_t qamEqCmaRad[]= {
|
|
DRXJ_16TO8( 13517 ), /* RAD0 */
|
|
DRXJ_16TO8( 13517 ), /* RAD1 */
|
|
DRXJ_16TO8( 13517 ), /* RAD2 */
|
|
DRXJ_16TO8( 13517 ), /* RAD3 */
|
|
DRXJ_16TO8( 13517 ), /* RAD4 */
|
|
DRXJ_16TO8( 13517 ), /* RAD5 */
|
|
};
|
|
|
|
WRB ( devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun), ((pu8_t)qamDqQualFun) );
|
|
WRB ( devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad), ((pu8_t)qamEqCmaRad) );
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RTH__A, 140);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FTH__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_PTH__A, 120);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_QTH__A, 230);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_CTH__A, 95);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MTH__A, 105);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t)(-24) );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t)(-65));
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t)(-127));
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 240);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM32 ()
|
|
* \brief QAM32 specific setup
|
|
* \param demod instance of demod.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM32 ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
|
|
const u8_t qamDqQualFun[]= {
|
|
DRXJ_16TO8( 3 ), /* fun0 */
|
|
DRXJ_16TO8( 3 ), /* fun1 */
|
|
DRXJ_16TO8( 3 ), /* fun2 */
|
|
DRXJ_16TO8( 3 ), /* fun3 */
|
|
DRXJ_16TO8( 4 ), /* fun4 */
|
|
DRXJ_16TO8( 4 ), /* fun5 */
|
|
};
|
|
const u8_t qamEqCmaRad[]= {
|
|
DRXJ_16TO8( 6707 ), /* RAD0 */
|
|
DRXJ_16TO8( 6707 ), /* RAD1 */
|
|
DRXJ_16TO8( 6707 ), /* RAD2 */
|
|
DRXJ_16TO8( 6707 ), /* RAD3 */
|
|
DRXJ_16TO8( 6707 ), /* RAD4 */
|
|
DRXJ_16TO8( 6707 ), /* RAD5 */
|
|
};
|
|
|
|
WRB ( devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun), ((pu8_t)qamDqQualFun) );
|
|
WRB ( devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad), ((pu8_t)qamEqCmaRad) );
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RTH__A, 90);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FTH__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_QTH__A, 170);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MTH__A, 100);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16_t)(-8) );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16_t)(-16) );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t)(-26) );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t)(-56));
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t)(-86));
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 176);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM64 ()
|
|
* \brief QAM64 specific setup
|
|
* \param demod instance of demod.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM64 ( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
|
|
const u8_t qamDqQualFun[]= { /* this is hw reset value. no necessary to re-write */
|
|
DRXJ_16TO8( 4 ), /* fun0 */
|
|
DRXJ_16TO8( 4 ), /* fun1 */
|
|
DRXJ_16TO8( 4 ), /* fun2 */
|
|
DRXJ_16TO8( 4 ), /* fun3 */
|
|
DRXJ_16TO8( 6 ), /* fun4 */
|
|
DRXJ_16TO8( 6 ), /* fun5 */
|
|
};
|
|
const u8_t qamEqCmaRad[]= {
|
|
DRXJ_16TO8( 13336 ), /* RAD0 */
|
|
DRXJ_16TO8( 12618 ), /* RAD1 */
|
|
DRXJ_16TO8( 11988 ), /* RAD2 */
|
|
DRXJ_16TO8( 13809 ), /* RAD3 */
|
|
DRXJ_16TO8( 13809 ), /* RAD4 */
|
|
DRXJ_16TO8( 15609 ), /* RAD5 */
|
|
};
|
|
|
|
WRB ( devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun), ((pu8_t)qamDqQualFun) );
|
|
WRB ( devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad), ((pu8_t)qamEqCmaRad) );
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RTH__A, 105);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_QTH__A, 195);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MTH__A, 84);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t)(-15));
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16_t)(-45));
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t)(-80));
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 160);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM128 ()
|
|
* \brief QAM128 specific setup
|
|
* \param demod: instance of demod.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM128( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
|
|
const u8_t qamDqQualFun[]= {
|
|
DRXJ_16TO8( 6 ), /* fun0 */
|
|
DRXJ_16TO8( 6 ), /* fun1 */
|
|
DRXJ_16TO8( 6 ), /* fun2 */
|
|
DRXJ_16TO8( 6 ), /* fun3 */
|
|
DRXJ_16TO8( 9 ), /* fun4 */
|
|
DRXJ_16TO8( 9 ), /* fun5 */
|
|
};
|
|
const u8_t qamEqCmaRad[]= {
|
|
DRXJ_16TO8( 6164 ), /* RAD0 */
|
|
DRXJ_16TO8( 6598 ), /* RAD1 */
|
|
DRXJ_16TO8( 6394 ), /* RAD2 */
|
|
DRXJ_16TO8( 6409 ), /* RAD3 */
|
|
DRXJ_16TO8( 6656 ), /* RAD4 */
|
|
DRXJ_16TO8( 7238 ), /* RAD5 */
|
|
};
|
|
|
|
WRB ( devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun), ((pu8_t)qamDqQualFun) );
|
|
WRB ( devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad), ((pu8_t)qamEqCmaRad) );
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RTH__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_QTH__A, 140);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MTH__A, 100);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3 );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16_t)(-1) );
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t)(-23));
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 144);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM256 ()
|
|
* \brief QAM256 specific setup
|
|
* \param demod: instance of demod.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM256( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = demod -> myI2CDevAddr;
|
|
const u8_t qamDqQualFun[]= {
|
|
DRXJ_16TO8( 8 ), /* fun0 */
|
|
DRXJ_16TO8( 8 ), /* fun1 */
|
|
DRXJ_16TO8( 8 ), /* fun2 */
|
|
DRXJ_16TO8( 8 ), /* fun3 */
|
|
DRXJ_16TO8( 12 ), /* fun4 */
|
|
DRXJ_16TO8( 12 ), /* fun5 */
|
|
};
|
|
const u8_t qamEqCmaRad[]= {
|
|
DRXJ_16TO8( 12345 ), /* RAD0 */
|
|
DRXJ_16TO8( 12345 ), /* RAD1 */
|
|
DRXJ_16TO8( 13626 ), /* RAD2 */
|
|
DRXJ_16TO8( 12931 ), /* RAD3 */
|
|
DRXJ_16TO8( 14719 ), /* RAD4 */
|
|
DRXJ_16TO8( 15356 ), /* RAD5 */
|
|
};
|
|
|
|
WRB ( devAddr, QAM_DQ_QUAL_FUN0__A, sizeof(qamDqQualFun), ((pu8_t)qamDqQualFun) );
|
|
WRB ( devAddr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qamEqCmaRad), ((pu8_t)qamEqCmaRad) );
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RTH__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FTH__A, 60);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_PTH__A, 100);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_QTH__A, 150);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_CTH__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MTH__A, 110);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0);
|
|
WR16 ( devAddr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16_t)(-8));
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF_COARSE__A, 80);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
|
|
WR16 ( devAddr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
|
|
|
|
WR16 ( devAddr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
#define QAM_SET_OP_ALL 0x1
|
|
#define QAM_SET_OP_CONSTELLATION 0x2
|
|
#define QAM_SET_OP_SPECTRUM 0X4
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAM ()
|
|
* \brief Set QAM demod.
|
|
* \param demod: instance of demod.
|
|
* \param channel: pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAM( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXFrequency_t tunerFreqOffset,
|
|
u32_t op
|
|
)
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
u16_t cmdResult = 0;
|
|
u32_t adcFrequency = 0;
|
|
u32_t iqmRcRate = 0;
|
|
u16_t lcSymbolFreq = 0;
|
|
u16_t iqmRcStretch = 0;
|
|
u16_t setEnvParameters = 0;
|
|
u16_t setParamParameters[2] = {0};
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* parameter */ NULL,
|
|
/* result */ NULL };
|
|
const u8_t qamA_taps[]= {
|
|
DRXJ_16TO8( -1 ), /* re0 */
|
|
DRXJ_16TO8( 1 ), /* re1 */
|
|
DRXJ_16TO8( 1 ), /* re2 */
|
|
DRXJ_16TO8( -1 ), /* re3 */
|
|
DRXJ_16TO8( -1 ), /* re4 */
|
|
DRXJ_16TO8( 2 ), /* re5 */
|
|
DRXJ_16TO8( 1 ), /* re6 */
|
|
DRXJ_16TO8( -2 ), /* re7 */
|
|
DRXJ_16TO8( 0 ), /* re8 */
|
|
DRXJ_16TO8( 3 ), /* re9 */
|
|
DRXJ_16TO8( -1 ), /* re10 */
|
|
DRXJ_16TO8( -3 ), /* re11 */
|
|
DRXJ_16TO8( 4 ), /* re12 */
|
|
DRXJ_16TO8( 1 ), /* re13 */
|
|
DRXJ_16TO8( -8 ), /* re14 */
|
|
DRXJ_16TO8( 4 ), /* re15 */
|
|
DRXJ_16TO8( 13 ), /* re16 */
|
|
DRXJ_16TO8( -13 ), /* re17 */
|
|
DRXJ_16TO8( -19 ), /* re18 */
|
|
DRXJ_16TO8( 28 ), /* re19 */
|
|
DRXJ_16TO8( 25 ), /* re20 */
|
|
DRXJ_16TO8( -53 ), /* re21 */
|
|
DRXJ_16TO8( -31 ), /* re22 */
|
|
DRXJ_16TO8( 96 ), /* re23 */
|
|
DRXJ_16TO8( 37 ), /* re24 */
|
|
DRXJ_16TO8( -190 ), /* re25 */
|
|
DRXJ_16TO8( -40 ), /* re26 */
|
|
DRXJ_16TO8( 619 ) /* re27 */
|
|
};
|
|
const u8_t qamB64_taps[]= {
|
|
DRXJ_16TO8( 0 ), /* re0 */
|
|
DRXJ_16TO8( -2 ), /* re1 */
|
|
DRXJ_16TO8( 1 ), /* re2 */
|
|
DRXJ_16TO8( 2 ), /* re3 */
|
|
DRXJ_16TO8( -2 ), /* re4 */
|
|
DRXJ_16TO8( 0 ), /* re5 */
|
|
DRXJ_16TO8( 4 ), /* re6 */
|
|
DRXJ_16TO8( -2 ), /* re7 */
|
|
DRXJ_16TO8( -4 ), /* re8 */
|
|
DRXJ_16TO8( 4 ), /* re9 */
|
|
DRXJ_16TO8( 3 ), /* re10 */
|
|
DRXJ_16TO8( -6 ), /* re11 */
|
|
DRXJ_16TO8( 0 ), /* re12 */
|
|
DRXJ_16TO8( 6 ), /* re13 */
|
|
DRXJ_16TO8( -5 ), /* re14 */
|
|
DRXJ_16TO8( -3 ), /* re15 */
|
|
DRXJ_16TO8( 11 ), /* re16 */
|
|
DRXJ_16TO8( -4 ), /* re17 */
|
|
DRXJ_16TO8( -19 ), /* re18 */
|
|
DRXJ_16TO8( 19 ), /* re19 */
|
|
DRXJ_16TO8( 28 ), /* re20 */
|
|
DRXJ_16TO8( -45 ), /* re21 */
|
|
DRXJ_16TO8( -36 ), /* re22 */
|
|
DRXJ_16TO8( 90 ), /* re23 */
|
|
DRXJ_16TO8( 42 ), /* re24 */
|
|
DRXJ_16TO8( -185 ), /* re25 */
|
|
DRXJ_16TO8( -46 ), /* re26 */
|
|
DRXJ_16TO8( 614 ) /* re27 */
|
|
};
|
|
const u8_t qamB256_taps[]= {
|
|
DRXJ_16TO8( -2 ), /* re0 */
|
|
DRXJ_16TO8( 4 ), /* re1 */
|
|
DRXJ_16TO8( 1 ), /* re2 */
|
|
DRXJ_16TO8( -4 ), /* re3 */
|
|
DRXJ_16TO8( 0 ), /* re4 */
|
|
DRXJ_16TO8( 4 ), /* re5 */
|
|
DRXJ_16TO8( -2 ), /* re6 */
|
|
DRXJ_16TO8( -4 ), /* re7 */
|
|
DRXJ_16TO8( 5 ), /* re8 */
|
|
DRXJ_16TO8( 2 ), /* re9 */
|
|
DRXJ_16TO8( -8 ), /* re10 */
|
|
DRXJ_16TO8( 2 ), /* re11 */
|
|
DRXJ_16TO8( 11 ), /* re12 */
|
|
DRXJ_16TO8( -8 ), /* re13 */
|
|
DRXJ_16TO8( -15 ), /* re14 */
|
|
DRXJ_16TO8( 16 ), /* re15 */
|
|
DRXJ_16TO8( 19 ), /* re16 */
|
|
DRXJ_16TO8( -27 ), /* re17 */
|
|
DRXJ_16TO8( -22 ), /* re18 */
|
|
DRXJ_16TO8( 44 ), /* re19 */
|
|
DRXJ_16TO8( 26 ), /* re20 */
|
|
DRXJ_16TO8( -69 ), /* re21 */
|
|
DRXJ_16TO8( -28 ), /* re22 */
|
|
DRXJ_16TO8( 110 ), /* re23 */
|
|
DRXJ_16TO8( 31 ), /* re24 */
|
|
DRXJ_16TO8( -201 ), /* re25 */
|
|
DRXJ_16TO8( -32 ), /* re26 */
|
|
DRXJ_16TO8( 628 ) /* re27 */
|
|
};
|
|
const u8_t qamC_taps[]= {
|
|
DRXJ_16TO8( -3 ), /* re0 */
|
|
DRXJ_16TO8( 3 ), /* re1 */
|
|
DRXJ_16TO8( 2 ), /* re2 */
|
|
DRXJ_16TO8( -4 ), /* re3 */
|
|
DRXJ_16TO8( 0 ), /* re4 */
|
|
DRXJ_16TO8( 4 ), /* re5 */
|
|
DRXJ_16TO8( -1 ), /* re6 */
|
|
DRXJ_16TO8( -4 ), /* re7 */
|
|
DRXJ_16TO8( 3 ), /* re8 */
|
|
DRXJ_16TO8( 3 ), /* re9 */
|
|
DRXJ_16TO8( -5 ), /* re10 */
|
|
DRXJ_16TO8( 0 ), /* re11 */
|
|
DRXJ_16TO8( 9 ), /* re12 */
|
|
DRXJ_16TO8( -4 ), /* re13 */
|
|
DRXJ_16TO8( -12 ), /* re14 */
|
|
DRXJ_16TO8( 10 ), /* re15 */
|
|
DRXJ_16TO8( 16 ), /* re16 */
|
|
DRXJ_16TO8( -21 ), /* re17 */
|
|
DRXJ_16TO8( -20 ), /* re18 */
|
|
DRXJ_16TO8( 37 ), /* re19 */
|
|
DRXJ_16TO8( 25 ), /* re20 */
|
|
DRXJ_16TO8( -62 ), /* re21 */
|
|
DRXJ_16TO8( -28 ), /* re22 */
|
|
DRXJ_16TO8( 105 ), /* re23 */
|
|
DRXJ_16TO8( 31 ), /* re24 */
|
|
DRXJ_16TO8( -197 ), /* re25 */
|
|
DRXJ_16TO8( -33 ), /* re26 */
|
|
DRXJ_16TO8( 626 ) /* re27 */
|
|
};
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION ))
|
|
{
|
|
if ( extAttr->standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
switch ( channel->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256 :
|
|
iqmRcRate = 0x00AE3562;
|
|
lcSymbolFreq = QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
|
|
channel->symbolrate = 5360537;
|
|
iqmRcStretch = IQM_RC_STRETCH_QAM_B_256;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64 :
|
|
iqmRcRate = 0x00C05A0E;
|
|
lcSymbolFreq = 409;
|
|
channel->symbolrate = 5056941;
|
|
iqmRcStretch = IQM_RC_STRETCH_QAM_B_64;
|
|
break;
|
|
default :
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
adcFrequency = ( commonAttr->sysClockFreq * 1000 ) / 3;
|
|
CHK_ZERO (channel->symbolrate);
|
|
iqmRcRate = ( adcFrequency / channel->symbolrate ) * ( 1 << 21 ) +
|
|
( Frac28 ( ( adcFrequency % channel->symbolrate ), channel->symbolrate ) >> 7 ) - ( 1 << 23 );
|
|
lcSymbolFreq = (u16_t)( Frac28 ( channel->symbolrate + (adcFrequency >> 13), adcFrequency ) >> 16 );
|
|
if (lcSymbolFreq > 511)
|
|
lcSymbolFreq = 511;
|
|
|
|
iqmRcStretch = 21;
|
|
}
|
|
|
|
if( extAttr->standard == DRX_STANDARD_ITU_A )
|
|
{
|
|
setEnvParameters = QAM_TOP_ANNEX_A; /* annex */
|
|
setParamParameters[0] = channel->constellation; /* constellation */
|
|
setParamParameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
|
|
}
|
|
else if( extAttr->standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
setEnvParameters = QAM_TOP_ANNEX_B; /* annex */
|
|
setParamParameters[0] = channel->constellation; /* constellation */
|
|
setParamParameters[1] = channel->interleavemode; /* interleave mode */
|
|
}
|
|
else if( extAttr->standard == DRX_STANDARD_ITU_C )
|
|
{
|
|
setEnvParameters = QAM_TOP_ANNEX_C; /* annex */
|
|
setParamParameters[0] = channel->constellation; /* constellation */
|
|
setParamParameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
|
|
}
|
|
else
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
|
|
if (op & QAM_SET_OP_ALL)
|
|
{
|
|
/*
|
|
STEP 1: reset demodulator
|
|
resets IQM, QAM and FEC HW blocks
|
|
resets SCU variables
|
|
*/
|
|
/* stop all comm_exec */
|
|
WR16( devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP );
|
|
WR16( devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_RESET;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
}
|
|
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION ))
|
|
{
|
|
/*
|
|
STEP 2: configure demodulator
|
|
-set env
|
|
-set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
|
|
*/
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
|
|
cmdSCU.parameterLen = 1;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = &setEnvParameters;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
|
|
cmdSCU.parameterLen = 2;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = setParamParameters;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
/* set symbol rate */
|
|
WR32( devAddr, IQM_RC_RATE_OFS_LO__A, iqmRcRate );
|
|
extAttr->iqmRcRateOfs = iqmRcRate;
|
|
CHK_ERROR( SetQAMMeasurement ( demod, channel->constellation, channel->symbolrate));
|
|
}
|
|
/* STEP 3: enable the system in a mode where the ADC provides valid signal
|
|
setup constellation independent registers */
|
|
/* from qam_cmd.py script (qam_driver_b)*/
|
|
/* TODO: remove re-writes of HW reset values */
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM ))
|
|
{
|
|
CHK_ERROR ( SetFrequency ( demod, channel, tunerFreqOffset ) );
|
|
}
|
|
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION ))
|
|
{
|
|
|
|
WR16( devAddr, QAM_LC_SYMBOL_FREQ__A, lcSymbolFreq);
|
|
WR16( devAddr, IQM_RC_STRETCH__A, iqmRcStretch );
|
|
}
|
|
|
|
if (op & QAM_SET_OP_ALL)
|
|
{
|
|
if (extAttr->hasLNA==FALSE)
|
|
{
|
|
WR16( devAddr, IQM_AF_AMUX__A, 0x02);
|
|
}
|
|
WR16( devAddr, IQM_CF_SYMMETRIC__A, 0 );
|
|
WR16( devAddr, IQM_CF_MIDTAP__A, 3 );
|
|
WR16( devAddr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M );
|
|
|
|
WR16( devAddr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f); /* scu temporary shut down agc */
|
|
|
|
WR16( devAddr, IQM_AF_SYNC_SEL__A, 3);
|
|
WR16( devAddr, IQM_AF_CLP_LEN__A, 0);
|
|
WR16( devAddr, IQM_AF_CLP_TH__A, 448);
|
|
WR16( devAddr, IQM_AF_SNS_LEN__A, 0);
|
|
WR16( devAddr, IQM_AF_PDREF__A, 4);
|
|
WR16( devAddr, IQM_AF_STDBY__A, 0x10);
|
|
WR16( devAddr, IQM_AF_PGA_GAIN__A, 11);
|
|
|
|
WR16( devAddr, IQM_CF_POW_MEAS_LEN__A, 1);
|
|
WR16( devAddr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); /*! reset default val ! */
|
|
|
|
WR16( devAddr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); /*! reset default val ! */
|
|
if( extAttr->standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
WR16( devAddr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE); /*! reset default val ! */
|
|
WR16( devAddr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE); /*! reset default val ! */
|
|
WR16( devAddr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
|
|
}
|
|
else
|
|
{
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_QAM16:
|
|
case DRX_CONSTELLATION_QAM64:
|
|
case DRX_CONSTELLATION_QAM256:
|
|
WR16( devAddr, QAM_SY_SYNC_LWM__A, 0x03);
|
|
WR16( devAddr, QAM_SY_SYNC_AWM__A, 0x04);
|
|
WR16( devAddr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
case DRX_CONSTELLATION_QAM128:
|
|
WR16( devAddr, QAM_SY_SYNC_LWM__A, 0x03);
|
|
WR16( devAddr, QAM_SY_SYNC_AWM__A, 0x05);
|
|
WR16( devAddr, QAM_SY_SYNC_HWM__A, 0x06);
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* switch */
|
|
}
|
|
|
|
WR16( devAddr, QAM_LC_MODE__A, QAM_LC_MODE__PRE); /*! reset default val ! */
|
|
WR16( devAddr, QAM_LC_RATE_LIMIT__A, 3);
|
|
WR16( devAddr, QAM_LC_LPF_FACTORP__A, 4);
|
|
WR16( devAddr, QAM_LC_LPF_FACTORI__A, 4);
|
|
WR16( devAddr, QAM_LC_MODE__A, 7);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB0__A, 1);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB1__A, 1);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB2__A, 1);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB3__A, 1);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB4__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB5__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB6__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB8__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB9__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB10__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB12__A, 2);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB15__A, 3);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB16__A, 3);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB20__A, 4);
|
|
WR16( devAddr, QAM_LC_QUAL_TAB25__A, 4);
|
|
|
|
WR16( devAddr, IQM_FS_ADJ_SEL__A, 1);
|
|
WR16( devAddr, IQM_RC_ADJ_SEL__A, 1);
|
|
WR16( devAddr, IQM_CF_ADJ_SEL__A, 1);
|
|
WR16( devAddr, IQM_CF_POW_MEAS_LEN__A, 0);
|
|
WR16( devAddr, SCU_RAM_GPIO__A, 0 );
|
|
|
|
/* No more resets of the IQM, current standard correctly set =>
|
|
now AGCs can be configured. */
|
|
/* turn on IQMAF. It has to be in front of setAgc**() */
|
|
CHK_ERROR( SetIqmAf( demod, TRUE ) );
|
|
CHK_ERROR(ADCSynchronization (demod));
|
|
|
|
CHK_ERROR( InitAGC( demod ) );
|
|
CHK_ERROR( SetAgcIf( demod, &(extAttr->qamIfAgcCfg), FALSE ) );
|
|
CHK_ERROR( SetAgcRf( demod, &(extAttr->qamRfAgcCfg), FALSE ) );
|
|
{
|
|
/* TODO fix this, store a DRXJCfgAfeGain_t structure in DRXJData_t instead
|
|
of only the gain */
|
|
DRXJCfgAfeGain_t qamPgaCfg = { DRX_STANDARD_ITU_B, 0 };
|
|
|
|
qamPgaCfg.gain = extAttr->qamPgaCfg;
|
|
CHK_ERROR( CtrlSetCfgAfeGain( demod, &qamPgaCfg ) );
|
|
}
|
|
CHK_ERROR( CtrlSetCfgPreSaw( demod, &(extAttr->qamPreSawCfg)) );
|
|
}
|
|
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION ))
|
|
{
|
|
if( extAttr->standard == DRX_STANDARD_ITU_A )
|
|
{
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A, sizeof(qamA_taps), ((pu8_t)qamA_taps) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A, sizeof(qamA_taps), ((pu8_t)qamA_taps) );
|
|
}
|
|
else if ( extAttr->standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_QAM64:
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A, sizeof(qamB64_taps), ((pu8_t)qamB64_taps) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A, sizeof(qamB64_taps), ((pu8_t)qamB64_taps) );
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A, sizeof(qamB256_taps), ((pu8_t)qamB256_taps) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A, sizeof(qamB256_taps), ((pu8_t)qamB256_taps) );
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
}
|
|
else if ( extAttr->standard == DRX_STANDARD_ITU_C )
|
|
{
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A, sizeof(qamC_taps), ((pu8_t)qamC_taps) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A, sizeof(qamC_taps), ((pu8_t)qamC_taps) );
|
|
}
|
|
|
|
/* SETP 4: constellation specific setup */
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_QAM16:
|
|
CHK_ERROR(SetQAM16( demod ));
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
CHK_ERROR(SetQAM32( demod ));
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
CHK_ERROR(SetQAM64( demod ));
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
CHK_ERROR(SetQAM128( demod ));
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
CHK_ERROR(SetQAM256( demod ));
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* switch */
|
|
}
|
|
|
|
if ((op & QAM_SET_OP_ALL))
|
|
{
|
|
WR16(devAddr, IQM_CF_SCALE_SH__A, 0 );
|
|
|
|
/* Mpeg output has to be in front of FEC active */
|
|
CHK_ERROR ( SetMPEGTEIHandling( demod ));
|
|
CHK_ERROR ( BitReverseMPEGOutput( demod ) );
|
|
CHK_ERROR ( SetMPEGStartWidth ( demod ) );
|
|
{
|
|
/* TODO: move to setStandard after hardware reset value problem is solved */
|
|
/* Configure initial MPEG output */
|
|
DRXCfgMPEGOutput_t cfgMPEGOutput;
|
|
|
|
cfgMPEGOutput.enableMPEGOutput = TRUE;
|
|
cfgMPEGOutput.insertRSByte = commonAttr->mpegCfg.insertRSByte;
|
|
cfgMPEGOutput.enableParallel = commonAttr->mpegCfg.enableParallel;
|
|
cfgMPEGOutput.invertDATA = commonAttr->mpegCfg.invertDATA;
|
|
cfgMPEGOutput.invertERR = commonAttr->mpegCfg.invertERR;
|
|
cfgMPEGOutput.invertSTR = commonAttr->mpegCfg.invertSTR;
|
|
cfgMPEGOutput.invertVAL = commonAttr->mpegCfg.invertVAL;
|
|
cfgMPEGOutput.invertCLK = commonAttr->mpegCfg.invertCLK;
|
|
cfgMPEGOutput.staticCLK = commonAttr->mpegCfg.staticCLK;
|
|
cfgMPEGOutput.bitrate = commonAttr->mpegCfg.bitrate;
|
|
CHK_ERROR( CtrlSetCfgMPEGOutput( demod, &cfgMPEGOutput) );
|
|
}
|
|
}
|
|
|
|
if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION ))
|
|
{
|
|
|
|
/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_START;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
}
|
|
|
|
WR16(devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE );
|
|
WR16(devAddr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE );
|
|
WR16(devAddr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
static DRXStatus_t
|
|
CtrlGetQAMSigQuality( pDRXDemodInstance_t demod,
|
|
pDRXSigQuality_t sigQuality );
|
|
static DRXStatus_t
|
|
qamFlipSpec ( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel)
|
|
{
|
|
u32_t iqmFsRateOfs = 0;
|
|
u32_t iqmFsRateLo = 0;
|
|
u16_t qamCtlEna = 0;
|
|
u16_t data = 0;
|
|
u16_t equMode = 0;
|
|
u16_t fsmState = 0;
|
|
int i = 0;
|
|
int ofsofs = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* Silence the controlling of lc, equ, and the acquisition state machine */
|
|
RR16( devAddr, SCU_RAM_QAM_CTL_ENA__A, &qamCtlEna );
|
|
WR16( devAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna
|
|
& ~ ( SCU_RAM_QAM_CTL_ENA_ACQ__M
|
|
| SCU_RAM_QAM_CTL_ENA_EQU__M
|
|
| SCU_RAM_QAM_CTL_ENA_LC__M) );
|
|
|
|
/* freeze the frequency control loop */
|
|
WR16( devAddr, QAM_LC_CF__A, 0);
|
|
WR16( devAddr, QAM_LC_CF1__A, 0);
|
|
|
|
ARR32( devAddr, IQM_FS_RATE_OFS_LO__A , &iqmFsRateOfs );
|
|
ARR32( devAddr, IQM_FS_RATE_LO__A, &iqmFsRateLo );
|
|
ofsofs = iqmFsRateLo - iqmFsRateOfs;
|
|
iqmFsRateOfs = ~iqmFsRateOfs + 1;
|
|
iqmFsRateOfs -= 2 * ofsofs;
|
|
|
|
/* freeze dq/fq updating */
|
|
RR16( devAddr, QAM_DQ_MODE__A, &data);
|
|
data = (data & 0xfff9);
|
|
WR16( devAddr, QAM_DQ_MODE__A, data );
|
|
WR16( devAddr, QAM_FQ_MODE__A, data );
|
|
|
|
/* lc_cp / _ci / _ca */
|
|
WR16( devAddr, QAM_LC_CI__A, 0 );
|
|
WR16( devAddr, QAM_LC_EP__A, 0 );
|
|
WR16( devAddr, QAM_FQ_LA_FACTOR__A, 0 );
|
|
|
|
/* flip the spec */
|
|
WR32( devAddr, IQM_FS_RATE_OFS_LO__A , iqmFsRateOfs );
|
|
extAttr->iqmFsRateOfs = iqmFsRateOfs;
|
|
extAttr->posImage = (extAttr->posImage)?FALSE:TRUE;
|
|
|
|
/* freeze dq/fq updating */
|
|
RR16( devAddr, QAM_DQ_MODE__A, &data);
|
|
equMode = data;
|
|
data = (data & 0xfff9);
|
|
WR16( devAddr, QAM_DQ_MODE__A, data );
|
|
WR16( devAddr, QAM_FQ_MODE__A, data );
|
|
|
|
for ( i = 0; i < 28; i++)
|
|
{
|
|
RR16( devAddr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data);
|
|
WR16( devAddr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data);
|
|
}
|
|
|
|
for ( i = 0; i < 24; i++)
|
|
{
|
|
RR16( devAddr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data);
|
|
WR16( devAddr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data);
|
|
}
|
|
|
|
data = equMode;
|
|
WR16( devAddr, QAM_DQ_MODE__A, data );
|
|
WR16( devAddr, QAM_FQ_MODE__A, data );
|
|
|
|
WR16( devAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4 );
|
|
|
|
i = 0;
|
|
while ( (fsmState != 4) && (i++ < 100) )
|
|
{
|
|
RR16( devAddr, SCU_RAM_QAM_FSM_STATE__A, &fsmState );
|
|
}
|
|
WR16( devAddr, SCU_RAM_QAM_CTL_ENA__A, (qamCtlEna | 0x0016) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
|
|
}
|
|
|
|
#define NO_LOCK 0x0
|
|
#define DEMOD_LOCKED 0x1
|
|
#define SYNC_FLIPPED 0x2
|
|
#define SPEC_MIRRORED 0x4
|
|
/**
|
|
* \fn DRXStatus_t QAM64Auto ()
|
|
* \brief auto do sync pattern switching and mirroring.
|
|
* \param demod: instance of demod.
|
|
* \param channel: pointer to channel data.
|
|
* \param tunerFreqOffset: tuner frequency offset.
|
|
* \param lockStatus: pointer to lock status.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
QAM64Auto( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXFrequency_t tunerFreqOffset,
|
|
pDRXLockStatus_t lockStatus
|
|
)
|
|
{
|
|
DRXSigQuality_t sigQuality;
|
|
u16_t data = 0;
|
|
u32_t state = NO_LOCK;
|
|
u32_t startTime = 0;
|
|
u32_t dLockedTime= 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
u32_t timeoutOfs = 0;
|
|
|
|
/* external attributes for storing aquired channel constellation */
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
*lockStatus = DRX_NOT_LOCKED;
|
|
startTime = DRXBSP_HST_Clock();
|
|
state = NO_LOCK;
|
|
do
|
|
{
|
|
CHK_ERROR( CtrlLockStatus(demod, lockStatus) );
|
|
|
|
switch (state)
|
|
{
|
|
case NO_LOCK:
|
|
if ( *lockStatus == DRXJ_DEMOD_LOCK )
|
|
{
|
|
CHK_ERROR ( CtrlGetQAMSigQuality ( demod, &sigQuality ) );
|
|
if (sigQuality.MER > 208)
|
|
{
|
|
state = DEMOD_LOCKED;
|
|
/* some delay to see if fec_lock possible TODO find the right value */
|
|
timeoutOfs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
|
|
dLockedTime = DRXBSP_HST_Clock();
|
|
}
|
|
}
|
|
break;
|
|
case DEMOD_LOCKED:
|
|
if ((*lockStatus == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms*/
|
|
((DRXBSP_HST_Clock() - dLockedTime) > DRXJ_QAM_FEC_LOCK_WAITTIME))
|
|
{
|
|
RR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, &data );
|
|
WR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, data | 0x1 );
|
|
state = SYNC_FLIPPED;
|
|
DRXBSP_HST_Sleep(10);
|
|
}
|
|
break;
|
|
case SYNC_FLIPPED:
|
|
if (*lockStatus == DRXJ_DEMOD_LOCK)
|
|
{
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
/* flip sync pattern back */
|
|
RR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, &data );
|
|
WR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, data & 0xFFFE );
|
|
/* flip spectrum */
|
|
extAttr->mirror = DRX_MIRROR_YES;
|
|
CHK_ERROR ( qamFlipSpec ( demod, channel ) );
|
|
state = SPEC_MIRRORED;
|
|
/* reset timer TODO: still need 500ms? */
|
|
startTime = dLockedTime = DRXBSP_HST_Clock();
|
|
timeoutOfs = 0;
|
|
}
|
|
else /* no need to wait lock */
|
|
{
|
|
startTime = DRXBSP_HST_Clock() - DRXJ_QAM_MAX_WAITTIME - timeoutOfs;
|
|
}
|
|
}
|
|
break;
|
|
case SPEC_MIRRORED:
|
|
if ((*lockStatus == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms*/
|
|
((DRXBSP_HST_Clock() - dLockedTime) > DRXJ_QAM_FEC_LOCK_WAITTIME))
|
|
{
|
|
CHK_ERROR ( CtrlGetQAMSigQuality ( demod, &sigQuality ) );
|
|
if (sigQuality.MER > 208)
|
|
{
|
|
RR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, &data );
|
|
WR16( demod->myI2CDevAddr, QAM_SY_TIMEOUT__A, data | 0x1 );
|
|
/* no need to wait lock */
|
|
startTime = DRXBSP_HST_Clock() - DRXJ_QAM_MAX_WAITTIME - timeoutOfs;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
DRXBSP_HST_Sleep(10);
|
|
} while
|
|
( ( *lockStatus != DRX_LOCKED ) &&
|
|
( *lockStatus != DRX_NEVER_LOCK ) &&
|
|
( (DRXBSP_HST_Clock() - startTime) < (DRXJ_QAM_MAX_WAITTIME + timeoutOfs))
|
|
);
|
|
/* Returning control to apllication ... */
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t QAM256Auto ()
|
|
* \brief auto do sync pattern switching and mirroring.
|
|
* \param demod: instance of demod.
|
|
* \param channel: pointer to channel data.
|
|
* \param tunerFreqOffset: tuner frequency offset.
|
|
* \param lockStatus: pointer to lock status.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
QAM256Auto( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXFrequency_t tunerFreqOffset,
|
|
pDRXLockStatus_t lockStatus
|
|
)
|
|
{
|
|
DRXSigQuality_t sigQuality;
|
|
u32_t state = NO_LOCK;
|
|
u32_t startTime = 0;
|
|
u32_t dLockedTime= 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
u32_t timeoutOfs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
|
|
|
|
/* external attributes for storing aquired channel constellation */
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
*lockStatus = DRX_NOT_LOCKED;
|
|
startTime = DRXBSP_HST_Clock();
|
|
state = NO_LOCK;
|
|
do
|
|
{
|
|
CHK_ERROR( CtrlLockStatus( demod, lockStatus) );
|
|
switch (state)
|
|
{
|
|
case NO_LOCK:
|
|
if ( *lockStatus == DRXJ_DEMOD_LOCK )
|
|
{
|
|
CHK_ERROR ( CtrlGetQAMSigQuality ( demod, &sigQuality ) );
|
|
if (sigQuality.MER > 268)
|
|
{
|
|
state = DEMOD_LOCKED;
|
|
timeoutOfs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
|
|
dLockedTime = DRXBSP_HST_Clock();
|
|
}
|
|
}
|
|
break;
|
|
case DEMOD_LOCKED:
|
|
if ( *lockStatus == DRXJ_DEMOD_LOCK )
|
|
{
|
|
if ((channel->mirror == DRX_MIRROR_AUTO) &&
|
|
((DRXBSP_HST_Clock() - dLockedTime) > DRXJ_QAM_FEC_LOCK_WAITTIME))
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_YES;
|
|
CHK_ERROR ( qamFlipSpec ( demod, channel ) );
|
|
state = SPEC_MIRRORED;
|
|
/* reset timer TODO: still need 300ms? */
|
|
startTime = DRXBSP_HST_Clock();
|
|
timeoutOfs = - DRXJ_QAM_MAX_WAITTIME / 2;
|
|
}
|
|
}
|
|
break;
|
|
case SPEC_MIRRORED:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
DRXBSP_HST_Sleep(10);
|
|
} while
|
|
( ( *lockStatus < DRX_LOCKED ) &&
|
|
( *lockStatus != DRX_NEVER_LOCK ) &&
|
|
( (DRXBSP_HST_Clock() - startTime) < (DRXJ_QAM_MAX_WAITTIME + timeoutOfs)) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetQAMChannel ()
|
|
* \brief Set QAM channel according to the requested constellation.
|
|
* \param demod: instance of demod.
|
|
* \param channel: pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetQAMChannel( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXFrequency_t tunerFreqOffset
|
|
)
|
|
{
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
pDRXJData_t extAttr = NULL;
|
|
Bool_t autoFlag = FALSE;
|
|
|
|
/* external attributes for storing aquired channel constellation */
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* set QAM channel constellation */
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_QAM16 :
|
|
case DRX_CONSTELLATION_QAM32 :
|
|
case DRX_CONSTELLATION_QAM64 :
|
|
case DRX_CONSTELLATION_QAM128 :
|
|
case DRX_CONSTELLATION_QAM256 :
|
|
extAttr->constellation = channel->constellation;
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
CHK_ERROR ( SetQAM( demod, channel, tunerFreqOffset, QAM_SET_OP_ALL) );
|
|
|
|
if ( (extAttr->standard == DRX_STANDARD_ITU_B) &&
|
|
(channel->constellation == DRX_CONSTELLATION_QAM64) )
|
|
{
|
|
CHK_ERROR ( QAM64Auto( demod, channel, tunerFreqOffset, &lockStatus));
|
|
}
|
|
|
|
if ( (extAttr->standard == DRX_STANDARD_ITU_B) &&
|
|
(channel->mirror == DRX_MIRROR_AUTO) &&
|
|
(channel->constellation == DRX_CONSTELLATION_QAM256) )
|
|
{
|
|
CHK_ERROR ( QAM256Auto( demod, channel, tunerFreqOffset, &lockStatus));
|
|
}
|
|
break;
|
|
case DRX_CONSTELLATION_AUTO: /* for channel scan */
|
|
if ( extAttr->standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
autoFlag = TRUE;
|
|
/* try to lock default QAM constellation: QAM64 */
|
|
channel->constellation = DRX_CONSTELLATION_QAM256;
|
|
extAttr->constellation = DRX_CONSTELLATION_QAM256;
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
CHK_ERROR ( SetQAM( demod, channel, tunerFreqOffset, QAM_SET_OP_ALL ) );
|
|
CHK_ERROR ( QAM256Auto( demod, channel, tunerFreqOffset, &lockStatus ));
|
|
|
|
if ( lockStatus < DRX_LOCKED )
|
|
{
|
|
/* QAM254 not locked -> try to lock QAM64 constellation */
|
|
channel->constellation = DRX_CONSTELLATION_QAM64;
|
|
extAttr->constellation = DRX_CONSTELLATION_QAM64;
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
{
|
|
u16_t qamCtlEna = 0;
|
|
RR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, &qamCtlEna );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna & ~SCU_RAM_QAM_CTL_ENA_ACQ__M );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2 ); /* force to rate hunting */
|
|
|
|
CHK_ERROR ( SetQAM( demod, channel, tunerFreqOffset, QAM_SET_OP_CONSTELLATION) );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna );
|
|
}
|
|
CHK_ERROR ( QAM64Auto( demod, channel, tunerFreqOffset, &lockStatus ));
|
|
}
|
|
channel->constellation = DRX_CONSTELLATION_AUTO;
|
|
}
|
|
else if ( extAttr->standard == DRX_STANDARD_ITU_C )
|
|
{
|
|
channel->constellation = DRX_CONSTELLATION_QAM64;
|
|
extAttr->constellation = DRX_CONSTELLATION_QAM64;
|
|
autoFlag = TRUE;
|
|
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
{
|
|
u16_t qamCtlEna = 0;
|
|
RR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, &qamCtlEna );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna & ~SCU_RAM_QAM_CTL_ENA_ACQ__M );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2 ); /* force to rate hunting */
|
|
|
|
CHK_ERROR ( SetQAM( demod, channel, tunerFreqOffset, QAM_SET_OP_CONSTELLATION) );
|
|
WR16( demod->myI2CDevAddr, SCU_RAM_QAM_CTL_ENA__A, qamCtlEna );
|
|
}
|
|
CHK_ERROR ( QAM64Auto( demod, channel, tunerFreqOffset, &lockStatus ));
|
|
channel->constellation = DRX_CONSTELLATION_AUTO;
|
|
}
|
|
else
|
|
{
|
|
channel->constellation = DRX_CONSTELLATION_AUTO;
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
/* restore starting value */
|
|
if (autoFlag)
|
|
channel->constellation = DRX_CONSTELLATION_AUTO;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn static short GetQAMRSErrCount(pI2CDeviceAddr_t devAddr)
|
|
* \brief Get RS error count in QAM mode (used for post RS BER calculation)
|
|
* \return Error code
|
|
*
|
|
* precondition: measurement period & measurement prescale must be set
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetQAMRSErrCount(pI2CDeviceAddr_t devAddr, pDRXJRSErrors_t RSErrors)
|
|
{
|
|
u16_t nrBitErrors = 0,
|
|
nrSymbolErrors = 0,
|
|
nrPacketErrors = 0,
|
|
nrFailures = 0,
|
|
nrSncParFailCount = 0;
|
|
|
|
/* check arguments */
|
|
if ( devAddr == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* all reported errors are received in the */
|
|
/* most recently finished measurment period */
|
|
/* no of pre RS bit errors */
|
|
RR16( devAddr, FEC_RS_NR_BIT_ERRORS__A, &nrBitErrors );
|
|
/* no of symbol errors */
|
|
RR16( devAddr, FEC_RS_NR_SYMBOL_ERRORS__A, &nrSymbolErrors );
|
|
/* no of packet errors */
|
|
RR16( devAddr, FEC_RS_NR_PACKET_ERRORS__A, &nrPacketErrors );
|
|
/* no of failures to decode */
|
|
RR16( devAddr, FEC_RS_NR_FAILURES__A, &nrFailures );
|
|
/* no of post RS bit erros */
|
|
RR16( devAddr, FEC_OC_SNC_FAIL_COUNT__A, &nrSncParFailCount );
|
|
/* TODO: NOTE */
|
|
/* These register values are fetched in non-atomic fashion */
|
|
/* It is possible that the read values contain unrelated information */
|
|
|
|
RSErrors->nrBitErrors = nrBitErrors & FEC_RS_NR_BIT_ERRORS__M;
|
|
RSErrors->nrSymbolErrors = nrSymbolErrors & FEC_RS_NR_SYMBOL_ERRORS__M;
|
|
RSErrors->nrPacketErrors = nrPacketErrors & FEC_RS_NR_PACKET_ERRORS__M;
|
|
RSErrors->nrFailures = nrFailures & FEC_RS_NR_FAILURES__M;
|
|
RSErrors->nrSncParFailCount = nrSncParFailCount & FEC_OC_SNC_FAIL_COUNT__M;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetQAMSigQuality()
|
|
* \brief Retreive QAM signal quality from device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param sigQuality Pointer to signal quality data.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigQuality contains valid data.
|
|
* \retval DRX_STS_INVALID_ARG sigQuality is NULL.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigQuality contains invalid data.
|
|
|
|
* Pre-condition: Device must be started and in lock.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetQAMSigQuality( pDRXDemodInstance_t demod,
|
|
pDRXSigQuality_t sigQuality )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXConstellation_t constellation = DRX_CONSTELLATION_UNKNOWN;
|
|
DRXJRSErrors_t measuredRSErrors = { 0, 0, 0, 0, 0 };
|
|
|
|
u32_t preBitErrRS = 0; /* pre RedSolomon Bit Error Rate */
|
|
u32_t postBitErrRS = 0; /* post RedSolomon Bit Error Rate */
|
|
u32_t pktErrs = 0; /* no of packet errors in RS */
|
|
u16_t qamSlErrPower = 0; /* accumulated error between raw and sliced symbols */
|
|
u16_t qsymErrVD = 0; /* quadrature symbol errors in QAM_VD */
|
|
u16_t fecOcPeriod = 0; /* SNC sync failure measurement period */
|
|
u16_t fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
|
|
u16_t fecRsPeriod = 0; /* Value for corresponding I2C register */
|
|
/* calculation constants */
|
|
u32_t rsBitCnt = 0; /* RedSolomon Bit Count */
|
|
u32_t qamSlSigPower = 0; /* used for MER, depends of QAM constellation */
|
|
/* intermediate results */
|
|
u32_t e = 0; /* exponent value used for QAM BER/SER */
|
|
u32_t m = 0; /* mantisa value used for QAM BER/SER */
|
|
u32_t berCnt = 0; /* BER count */
|
|
/* signal quality info */
|
|
u32_t qamSlMer = 0; /* QAM MER */
|
|
u32_t qamPreRSBer = 0; /* Pre RedSolomon BER */
|
|
u32_t qamPostRSBer = 0; /* Post RedSolomon BER */
|
|
u32_t qamVDSer = 0; /* ViterbiDecoder SER */
|
|
u16_t qamVdPrescale = 0; /* Viterbi Measurement Prescale */
|
|
u16_t qamVdPeriod = 0; /* Viterbi Measurement period */
|
|
u32_t vdBitCnt = 0; /* ViterbiDecoder Bit Count */
|
|
|
|
/* get device basic information */
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
constellation = extAttr->constellation;
|
|
|
|
/* read the physical registers */
|
|
/* Get the RS error data */
|
|
CHK_ERROR ( GetQAMRSErrCount ( devAddr, &measuredRSErrors ) );
|
|
/* get the register value needed for MER */
|
|
RR16( devAddr, QAM_SL_ERR_POWER__A, &qamSlErrPower );
|
|
/* get the register value needed for post RS BER */
|
|
RR16 ( devAddr, FEC_OC_SNC_FAIL_PERIOD__A, &fecOcPeriod );
|
|
|
|
/* get constants needed for signal quality calculation */
|
|
fecRsPeriod = extAttr->fecRsPeriod;
|
|
fecRsPrescale = extAttr->fecRsPrescale;
|
|
rsBitCnt = fecRsPeriod * fecRsPrescale * extAttr->fecRsPlen;
|
|
qamVdPeriod = extAttr->qamVdPeriod;
|
|
qamVdPrescale = extAttr->qamVdPrescale;
|
|
vdBitCnt = qamVdPeriod * qamVdPrescale * extAttr->fecVdPlen;
|
|
|
|
/* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
|
|
switch ( constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM16:
|
|
qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM256:
|
|
qamSlSigPower = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* ------------------------------ */
|
|
/* MER Calculation */
|
|
/* ------------------------------ */
|
|
/* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
|
|
|
|
/* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
|
|
if ( qamSlErrPower == 0 )
|
|
qamSlMer = 0;
|
|
else
|
|
qamSlMer = Log10Times100( qamSlSigPower ) - Log10Times100( ( u32_t ) qamSlErrPower );
|
|
|
|
|
|
/* ----------------------------------------- */
|
|
/* Pre Viterbi Symbol Error Rate Calculation */
|
|
/* ----------------------------------------- */
|
|
/* pre viterbi SER is good if it is bellow 0.025 */
|
|
|
|
/* get the register value */
|
|
/* no of quadrature symbol errors */
|
|
RR16( devAddr, QAM_VD_NR_QSYM_ERRORS__A , &qsymErrVD );
|
|
/* Extract the Exponent and the Mantisa */
|
|
/* of number of quadrature symbol errors */
|
|
e = ( qsymErrVD & QAM_VD_NR_QSYM_ERRORS_EXP__M ) >>
|
|
QAM_VD_NR_QSYM_ERRORS_EXP__B;
|
|
m = ( qsymErrVD & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M ) >>
|
|
QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
|
|
|
|
if ( (m << e) >> 3 > 549752 ) /* the max of FracTimes1e6 */
|
|
{
|
|
qamVDSer = 500000; /* clip BER 0.5 */
|
|
}
|
|
else
|
|
{
|
|
qamVDSer = FracTimes1e6(m << ((e > 2)? (e - 3):e), vdBitCnt * ((e > 2)?1:8) / 8 );
|
|
}
|
|
|
|
/* --------------------------------------- */
|
|
/* pre and post RedSolomon BER Calculation */
|
|
/* --------------------------------------- */
|
|
/* pre RS BER is good if it is below 3.5e-4 */
|
|
|
|
/* get the register values */
|
|
preBitErrRS = ( u32_t ) measuredRSErrors.nrBitErrors;
|
|
pktErrs = postBitErrRS = ( u32_t ) measuredRSErrors.nrSncParFailCount;
|
|
|
|
/* Extract the Exponent and the Mantisa of the */
|
|
/* pre Reed-Solomon bit error count */
|
|
e = ( preBitErrRS & FEC_RS_NR_BIT_ERRORS_EXP__M ) >>
|
|
FEC_RS_NR_BIT_ERRORS_EXP__B;
|
|
m = ( preBitErrRS & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M ) >>
|
|
FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
|
|
|
|
berCnt = m << e;
|
|
|
|
/*qamPreRSBer = FracTimes1e6( berCnt, rsBitCnt ); */
|
|
if ( m > (rsBitCnt >> (e + 1)) || (rsBitCnt >> e) == 0 )
|
|
{
|
|
qamPreRSBer = 500000; /* clip BER 0.5 */
|
|
}
|
|
else
|
|
{
|
|
qamPreRSBer = FracTimes1e6(m, rsBitCnt >> e );
|
|
}
|
|
|
|
/* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
|
|
/* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
|
|
/*
|
|
=> c = (1000000*100*11.17)/1504 =
|
|
post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
|
|
(100 * FEC_OC_SNC_FAIL_PERIOD__A)
|
|
*100 and /100 is for more precision.
|
|
=> (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
|
|
|
|
Precision errors still possible.
|
|
*/
|
|
e = postBitErrRS * 742686;
|
|
m = fecOcPeriod * 100;
|
|
if ( fecOcPeriod == 0 )
|
|
qamPostRSBer = 0xFFFFFFFF;
|
|
else
|
|
qamPostRSBer = e/m;
|
|
|
|
/* fill signal quality data structure */
|
|
sigQuality->MER = ( ( u16_t ) qamSlMer );
|
|
if (extAttr->standard == DRX_STANDARD_ITU_B)
|
|
{
|
|
sigQuality->preViterbiBER = qamVDSer;
|
|
}
|
|
else
|
|
{
|
|
sigQuality->preViterbiBER = qamPreRSBer;
|
|
}
|
|
sigQuality->postViterbiBER = qamPreRSBer;
|
|
sigQuality->postReedSolomonBER = qamPostRSBer;
|
|
sigQuality->scaleFactorBER = ( ( u32_t ) 1000000 );
|
|
#ifdef DRXJ_SIGNAL_ACCUM_ERR
|
|
CHK_ERROR (GetAccPktErr (demod, &sigQuality->packetError));
|
|
#else
|
|
sigQuality->packetError = ( ( u16_t ) pktErrs );
|
|
#endif
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetQAMConstel()
|
|
* \brief Retreive a QAM constellation point via I2C.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param complexNr Pointer to the structure in which to store the
|
|
constellation point.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetQAMConstel( pDRXDemodInstance_t demod,
|
|
pDRXComplex_t complexNr )
|
|
{
|
|
u16_t fecOcOcrMode = 0; /**< FEC OCR grabber configuration */
|
|
u16_t qamSlCommMb = 0; /**< QAM SL MB configuration */
|
|
u16_t qamSlCommMbInit = 0; /**< QAM SL MB intial configuration */
|
|
u16_t im = 0; /**< constellation Im part */
|
|
u16_t re = 0; /**< constellation Re part */
|
|
u32_t data = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL; /**< device address */
|
|
|
|
/* read device info */
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* TODO: */
|
|
/* Monitor bus grabbing is an open external interface issue */
|
|
/* Needs to be checked when external interface PG is updated */
|
|
|
|
/* Configure MB (Monitor bus) */
|
|
RR16( devAddr, QAM_SL_COMM_MB__A, &qamSlCommMbInit );
|
|
/* set observe flag & MB mux */
|
|
qamSlCommMb = qamSlCommMbInit & (~ ( QAM_SL_COMM_MB_OBS__M +
|
|
QAM_SL_COMM_MB_MUX_OBS__M ) );
|
|
qamSlCommMb |= ( QAM_SL_COMM_MB_OBS_ON +
|
|
QAM_SL_COMM_MB_MUX_OBS_CONST_CORR );
|
|
WR16( devAddr, QAM_SL_COMM_MB__A, qamSlCommMb );
|
|
|
|
/* Enable MB grabber in the FEC OC */
|
|
fecOcOcrMode = ( /* output select: observe bus */
|
|
( FEC_OC_OCR_MODE_MB_SELECT__M &
|
|
( 0x0 << FEC_OC_OCR_MODE_MB_SELECT__B ) ) |
|
|
/* grabber enable: on */
|
|
( FEC_OC_OCR_MODE_GRAB_ENABLE__M &
|
|
( 0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B ) ) |
|
|
/* grabber select: observe bus */
|
|
( FEC_OC_OCR_MODE_GRAB_SELECT__M &
|
|
( 0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B ) ) |
|
|
/* grabber mode: continuous */
|
|
( FEC_OC_OCR_MODE_GRAB_COUNTED__M &
|
|
( 0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B ) ) );
|
|
WR16( devAddr, FEC_OC_OCR_MODE__A, fecOcOcrMode );
|
|
|
|
/* Disable MB grabber in the FEC OC */
|
|
WR16( devAddr, FEC_OC_OCR_MODE__A, 0x00 );
|
|
|
|
/* read data */
|
|
RR32( devAddr, FEC_OC_OCR_GRAB_RD0__A, &data );
|
|
re = (u16_t)(data & FEC_OC_OCR_GRAB_RD0__M);
|
|
im = (u16_t)((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
|
|
|
|
/* TODO: */
|
|
/* interpret data (re & im) according to the Monitor bus mapping ?? */
|
|
|
|
/* sign extension, 10th bit is sign bit */
|
|
if ( (re & 0x0200) == 0x0200 )
|
|
{
|
|
re |= 0xFC00;
|
|
}
|
|
if ( (im & 0x0200) == 0x0200 )
|
|
{
|
|
im |= 0xFC00;
|
|
}
|
|
complexNr->re = ( ( s16_t ) re ) ;
|
|
complexNr->im = ( ( s16_t ) im ) ;
|
|
|
|
/* Restore MB (Monitor bus) */
|
|
WR16( devAddr, QAM_SL_COMM_MB__A, qamSlCommMbInit );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif /* #ifndef DRXJ_VSB_ONLY */
|
|
|
|
/*============================================================================*/
|
|
/*== END QAM DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== ATV DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
|
|
/*
|
|
Implementation notes.
|
|
|
|
NTSC/FM AGCs
|
|
|
|
Four AGCs are used for NTSC:
|
|
(1) RF (used to attenuate the input signal in case of to much power)
|
|
(2) IF (used to attenuate the input signal in case of to much power)
|
|
(3) Video AGC (used to amplify the output signal in case input to low)
|
|
(4) SIF AGC (used to amplify the output signal in case input to low)
|
|
|
|
Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
|
|
that the coupling between Video AGC and the RF and IF AGCs also works in
|
|
favor of the SIF AGC.
|
|
|
|
Three AGCs are used for FM:
|
|
(1) RF (used to attenuate the input signal in case of to much power)
|
|
(2) IF (used to attenuate the input signal in case of to much power)
|
|
(3) SIF AGC (used to amplify the output signal in case input to low)
|
|
|
|
The SIF AGC is now coupled to the RF/IF AGCs.
|
|
The SIF AGC is needed for both SIF ouput and the internal SIF signal to
|
|
the AUD block.
|
|
|
|
RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
|
|
the ATV block. The AGC control algorithms are all implemented in
|
|
microcode.
|
|
|
|
ATV SETTINGS
|
|
|
|
(Shadow settings will not be used for now, they will be implemented
|
|
later on because of the schedule)
|
|
|
|
Several HW/SCU "settings" can be used for ATV. The standard selection
|
|
will reset most of these settings. To avoid that the end user apllication
|
|
has to perform these settings each time the ATV or FM standards is
|
|
selected the driver will shadow these settings. This enables the end user
|
|
to perform the settings only once after a DRX_Open(). The driver must
|
|
write the shadow settings to HW/SCU incase:
|
|
( setstandard FM/ATV) ||
|
|
( settings have changed && FM/ATV standard is active)
|
|
The shadow settings will be stored in the device specific data container.
|
|
A set of flags will be defined to flag changes in shadow settings.
|
|
A routine will be implemented to write all changed shadow settings to
|
|
HW/SCU.
|
|
|
|
The "settings" will consist of: AGC settings, filter settings etc.
|
|
|
|
Disadvantage of use of shadow settings:
|
|
Direct changes in HW/SCU registers will not be reflected in the
|
|
shadow settings and these changes will be overwritten during a next
|
|
update. This can happen during evaluation. This will not be a problem
|
|
for normal customer usage.
|
|
*/
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* \brief Get array index for atv coef (extAttr->atvTopCoefX[index])
|
|
* \param standard
|
|
* \param pointer to index
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AtvEquCoefIndex( DRXStandard_t standard, int *index)
|
|
{
|
|
switch(standard)
|
|
{
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
*index=(int)DRXJ_COEF_IDX_BG;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
*index=(int)DRXJ_COEF_IDX_DK;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
*index=(int)DRXJ_COEF_IDX_I;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
*index=(int)DRXJ_COEF_IDX_L;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
*index=(int)DRXJ_COEF_IDX_LP;
|
|
break;
|
|
case DRX_STANDARD_NTSC:
|
|
*index=(int)DRXJ_COEF_IDX_MN;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
*index=(int)DRXJ_COEF_IDX_FM;
|
|
break;
|
|
default:
|
|
*index=(int)DRXJ_COEF_IDX_MN; /* still return a valid index */
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t AtvUpdateConfig ()
|
|
* \brief Flush changes in ATV shadow registers to physical registers.
|
|
* \param demod instance of demodulator
|
|
* \param forceUpdate don't look at standard or change flags, flush all.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AtvUpdateConfig( pDRXDemodInstance_t demod,
|
|
Bool_t forceUpdate )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* equalizer coefficients */
|
|
if ( forceUpdate ||
|
|
((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_COEF) != 0) )
|
|
{
|
|
int index=0;
|
|
|
|
CHK_ERROR(AtvEquCoefIndex( extAttr->standard, &index ));
|
|
WR16( devAddr, ATV_TOP_EQU0__A, extAttr->atvTopEqu0[index] );
|
|
WR16( devAddr, ATV_TOP_EQU1__A, extAttr->atvTopEqu1[index] );
|
|
WR16( devAddr, ATV_TOP_EQU2__A, extAttr->atvTopEqu2[index] );
|
|
WR16( devAddr, ATV_TOP_EQU3__A, extAttr->atvTopEqu3[index] );
|
|
}
|
|
|
|
/* bypass fast carrier recovery */
|
|
if ( forceUpdate )
|
|
{
|
|
u16_t data=0;
|
|
|
|
RR16( devAddr, IQM_RT_ROT_BP__A, &data );
|
|
data &= (~((u16_t)IQM_RT_ROT_BP_ROT_OFF__M));
|
|
if (extAttr->phaseCorrectionBypass)
|
|
{
|
|
data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
|
|
} else {
|
|
data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
|
|
}
|
|
WR16( devAddr, IQM_RT_ROT_BP__A, data );
|
|
}
|
|
|
|
/* peak filter setting */
|
|
if ( forceUpdate ||
|
|
((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0) )
|
|
{
|
|
WR16( devAddr, ATV_TOP_VID_PEAK__A, extAttr->atvTopVidPeak );
|
|
}
|
|
|
|
/* noise filter setting */
|
|
if ( forceUpdate ||
|
|
((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0) )
|
|
{
|
|
WR16( devAddr, ATV_TOP_NOISE_TH__A, extAttr->atvTopNoiseTh );
|
|
}
|
|
|
|
/* SIF attenuation */
|
|
if ( forceUpdate ||
|
|
((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_SIF_ATT) != 0) )
|
|
{
|
|
u16_t attenuation=0;
|
|
|
|
switch( extAttr->sifAttenuation ){
|
|
case DRXJ_SIF_ATTENUATION_0DB:
|
|
attenuation = ATV_TOP_AF_SIF_ATT_0DB;
|
|
break;
|
|
case DRXJ_SIF_ATTENUATION_3DB:
|
|
attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
|
|
break;
|
|
case DRXJ_SIF_ATTENUATION_6DB:
|
|
attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
|
|
break;
|
|
case DRXJ_SIF_ATTENUATION_9DB:
|
|
attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
WR16( devAddr, ATV_TOP_AF_SIF_ATT__A, attenuation );
|
|
}
|
|
|
|
/* SIF & CVBS enable */
|
|
if ( forceUpdate ||
|
|
((extAttr->atvCfgChangedFlags & DRXJ_ATV_CHANGED_OUTPUT) != 0) )
|
|
{
|
|
u16_t data = 0;
|
|
|
|
RR16( devAddr, ATV_TOP_STDBY__A, &data );
|
|
if ( extAttr->enableCVBSOutput )
|
|
{
|
|
data |=ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
|
|
} else {
|
|
data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
|
|
}
|
|
|
|
if ( extAttr->enableSIFOutput )
|
|
{
|
|
data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
|
|
} else {
|
|
data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
|
|
}
|
|
WR16( devAddr, ATV_TOP_STDBY__A, data );
|
|
}
|
|
|
|
extAttr->atvCfgChangedFlags = 0;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgATVOutput()
|
|
* \brief Configure ATV ouputs
|
|
* \param demod instance of demodulator
|
|
* \param outputCfg output configuaration
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgATVOutput( pDRXDemodInstance_t demod,
|
|
pDRXJCfgAtvOutput_t outputCfg )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* Check arguments */
|
|
if ( outputCfg == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
if ( outputCfg->enableSIFOutput )
|
|
{
|
|
switch( outputCfg->sifAttenuation ){
|
|
case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
|
|
case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
|
|
case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
|
|
case DRXJ_SIF_ATTENUATION_9DB:
|
|
/* Do nothing */
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
if(extAttr->sifAttenuation != outputCfg->sifAttenuation )
|
|
{
|
|
extAttr->sifAttenuation = outputCfg->sifAttenuation;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_SIF_ATT;
|
|
}
|
|
}
|
|
|
|
if ( extAttr->enableCVBSOutput != outputCfg->enableCVBSOutput )
|
|
{
|
|
extAttr->enableCVBSOutput = outputCfg->enableCVBSOutput;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_OUTPUT;
|
|
}
|
|
|
|
if ( extAttr->enableSIFOutput != outputCfg->enableSIFOutput )
|
|
{
|
|
extAttr->enableSIFOutput = outputCfg->enableSIFOutput;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_OUTPUT;
|
|
}
|
|
|
|
CHK_ERROR( AtvUpdateConfig(demod, FALSE) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgAtvEquCoef()
|
|
* \brief Set ATV equalizer coefficients
|
|
* \param demod instance of demodulator
|
|
* \param coef the equalizer coefficients
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgAtvEquCoef( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvEquCoef_t coef)
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
int index;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* current standard needs to be an ATV standard */
|
|
if (!DRXJ_ISATVSTD(extAttr->standard ))
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* Check arguments */
|
|
if ( ( coef == NULL ) ||
|
|
( coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2) ) ||
|
|
( coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2) ) ||
|
|
( coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2) ) ||
|
|
( coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2) ) ||
|
|
( coef->coef0 < ((s16_t)~(ATV_TOP_EQU0_EQU_C0__M >> 1)) ) ||
|
|
( coef->coef1 < ((s16_t)~(ATV_TOP_EQU1_EQU_C1__M >> 1)) ) ||
|
|
( coef->coef2 < ((s16_t)~(ATV_TOP_EQU2_EQU_C2__M >> 1)) ) ||
|
|
( coef->coef3 < ((s16_t)~(ATV_TOP_EQU3_EQU_C3__M >> 1)) ) )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
CHK_ERROR(AtvEquCoefIndex( extAttr->standard, &index ));
|
|
extAttr->atvTopEqu0[index] = coef->coef0;
|
|
extAttr->atvTopEqu1[index] = coef->coef1;
|
|
extAttr->atvTopEqu2[index] = coef->coef2;
|
|
extAttr->atvTopEqu3[index] = coef->coef3;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_COEF;
|
|
|
|
CHK_ERROR( AtvUpdateConfig(demod, FALSE) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAtvEquCoef()
|
|
* \brief Get ATV equ coef settings
|
|
* \param demod instance of demodulator
|
|
* \param coef The ATV equ coefficients
|
|
* \return DRXStatus_t.
|
|
*
|
|
* The values are read from the shadow registers maintained by the drxdriver
|
|
* If registers are manipulated outside of the drxdriver scope the reported
|
|
* settings will not reflect these changes because of the use of shadow
|
|
* regitsers.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAtvEquCoef( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvEquCoef_t coef)
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
int index=0;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* current standard needs to be an ATV standard */
|
|
if (!DRXJ_ISATVSTD(extAttr->standard ))
|
|
{
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* Check arguments */
|
|
if ( coef == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
CHK_ERROR(AtvEquCoefIndex( extAttr->standard, &index ));
|
|
coef->coef0 = extAttr->atvTopEqu0[index];
|
|
coef->coef1 = extAttr->atvTopEqu1[index];
|
|
coef->coef2 = extAttr->atvTopEqu2[index];
|
|
coef->coef3 = extAttr->atvTopEqu3[index];
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgAtvMisc()
|
|
* \brief Set misc. settings for ATV.
|
|
* \param demod instance of demodulator
|
|
* \param
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgAtvMisc( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvMisc_t settings )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* Check arguments */
|
|
if ( ( settings == NULL ) ||
|
|
((settings->peakFilter) < (s16_t)(-8) ) ||
|
|
((settings->peakFilter) > (s16_t)(15) ) ||
|
|
((settings->noiseFilter) > 15 ) )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
} /* if */
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
if ( settings->peakFilter != extAttr->atvTopVidPeak )
|
|
{
|
|
extAttr->atvTopVidPeak = settings->peakFilter;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_PEAK_FLT;
|
|
}
|
|
|
|
if ( settings->noiseFilter != extAttr->atvTopNoiseTh )
|
|
{
|
|
extAttr->atvTopNoiseTh = settings->noiseFilter;
|
|
extAttr->atvCfgChangedFlags |= DRXJ_ATV_CHANGED_NOISE_FLT;
|
|
}
|
|
|
|
CHK_ERROR( AtvUpdateConfig(demod, FALSE) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAtvMisc()
|
|
* \brief Get misc settings of ATV.
|
|
* \param demod instance of demodulator
|
|
* \param settings misc. ATV settings
|
|
* \return DRXStatus_t.
|
|
*
|
|
* The values are read from the shadow registers maintained by the drxdriver
|
|
* If registers are manipulated outside of the drxdriver scope the reported
|
|
* settings will not reflect these changes because of the use of shadow
|
|
* regitsers.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAtvMisc( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvMisc_t settings )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* Check arguments */
|
|
if ( settings == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
settings->peakFilter = extAttr->atvTopVidPeak ;
|
|
settings->noiseFilter = extAttr->atvTopNoiseTh ;
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAtvOutput()
|
|
* \brief
|
|
* \param demod instance of demodulator
|
|
* \param outputCfg output configuaration
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAtvOutput( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvOutput_t outputCfg )
|
|
{
|
|
u16_t data = 0;
|
|
|
|
/* Check arguments */
|
|
if ( outputCfg == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
RR16( demod->myI2CDevAddr, ATV_TOP_STDBY__A, &data );
|
|
if ( data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE )
|
|
{
|
|
outputCfg->enableCVBSOutput = TRUE;
|
|
} else {
|
|
outputCfg->enableCVBSOutput = FALSE;
|
|
}
|
|
|
|
if ( data & ATV_TOP_STDBY_SIF_STDBY_STANDBY )
|
|
{
|
|
outputCfg->enableSIFOutput = FALSE;
|
|
} else {
|
|
outputCfg->enableSIFOutput = TRUE;
|
|
RR16( demod->myI2CDevAddr, ATV_TOP_AF_SIF_ATT__A, &data );
|
|
outputCfg->sifAttenuation = (DRXJSIFAttenuation_t) data;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAtvAgcStatus()
|
|
* \brief
|
|
* \param demod instance of demodulator
|
|
* \param agcStatus agc status
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAtvAgcStatus( pDRXDemodInstance_t demod ,
|
|
pDRXJCfgAtvAgcStatus_t agcStatus )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
u16_t data = 0;
|
|
u32_t tmp = 0;
|
|
|
|
/* Check arguments */
|
|
if ( agcStatus == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/*
|
|
RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
|
|
= ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
|
|
|
|
IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
|
|
*/
|
|
RR16( devAddr, IQM_AF_AGC_RF__A, &data );
|
|
tmp = ((u32_t)data) * 27 - ((u32_t)(data>>2)); /* nA */
|
|
agcStatus->rfAgcGain = (u16_t)(tmp/1000) ; /* uA */
|
|
/* rounding */
|
|
if ( tmp%1000 >= 500 )
|
|
{
|
|
(agcStatus->rfAgcGain)++;
|
|
}
|
|
|
|
/*
|
|
IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
|
|
= ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
|
|
|
|
IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
|
|
*/
|
|
RR16( devAddr, IQM_AF_AGC_IF__A, &data );
|
|
tmp = ((u32_t)data) * 27 - ((u32_t)(data>>2)); /* nA */
|
|
agcStatus->ifAgcGain = (u16_t)(tmp/1000) ; /* uA */
|
|
/* rounding */
|
|
if ( tmp%1000 >= 500 )
|
|
{
|
|
(agcStatus->ifAgcGain)++;
|
|
}
|
|
|
|
/*
|
|
videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
|
|
= (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
|
|
= 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
|
|
= (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
|
|
= (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
|
|
*/
|
|
|
|
SARR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A , &data );
|
|
/* dividing by 32 inclusive rounding */
|
|
data >>=4;
|
|
if ((data & 1) !=0 )
|
|
{
|
|
data++;
|
|
}
|
|
data >>= 1;
|
|
agcStatus->videoAgcGain = ((s16_t)data)-75; /* 0.1 dB */
|
|
|
|
/*
|
|
audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
|
|
= (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
|
|
= 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
|
|
= (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
|
|
= (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
|
|
*/
|
|
|
|
SARR16( devAddr, SCU_RAM_ATV_SIF_GAIN__A, &data );
|
|
data &= SCU_RAM_ATV_SIF_GAIN__M;
|
|
/* dividing by 2 inclusive rounding */
|
|
if ((data & 1) !=0 )
|
|
{
|
|
data++;
|
|
}
|
|
data >>= 1;
|
|
agcStatus->audioAgcGain = ((s16_t)data)-4; /* 0.1 dB */
|
|
|
|
/* Loop gain's */
|
|
SARR16( devAddr, SCU_RAM_AGC_KI__A, &data );
|
|
agcStatus->videoAgcLoopGain =
|
|
( (data & SCU_RAM_AGC_KI_DGAIN__M)>>SCU_RAM_AGC_KI_DGAIN__B) ;
|
|
agcStatus->rfAgcLoopGain =
|
|
( (data & SCU_RAM_AGC_KI_RF__M)>>SCU_RAM_AGC_KI_RF__B) ;
|
|
agcStatus->ifAgcLoopGain =
|
|
( (data & SCU_RAM_AGC_KI_IF__M)>>SCU_RAM_AGC_KI_IF__B) ;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* \fn DRXStatus_t PowerUpATV ()
|
|
* \brief Power up ATV.
|
|
* \param demod instance of demodulator
|
|
* \param standard either NTSC or FM (sub strandard for ATV )
|
|
* \return DRXStatus_t.
|
|
*
|
|
* * Starts ATV and IQM
|
|
* * AUdio already started during standard init for ATV.
|
|
*/
|
|
static DRXStatus_t
|
|
PowerUpATV( pDRXDemodInstance_t demod , DRXStandard_t standard )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* ATV NTSC */
|
|
WR16( devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE );
|
|
/* turn on IQM_AF */
|
|
CHK_ERROR( SetIqmAf( demod, TRUE ) );
|
|
CHK_ERROR(ADCSynchronization (demod));
|
|
|
|
WR16( devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE );
|
|
|
|
/* Audio, already done during set standard */
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif /* #ifndef DRXJ_DIGITAL_ONLY */
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* \fn DRXStatus_t PowerDownATV ()
|
|
* \brief Power down ATV.
|
|
* \param demod instance of demodulator
|
|
* \param standard either NTSC or FM (sub strandard for ATV )
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Stops and thus resets ATV and IQM block
|
|
* SIF and CVBS ADC are powered down
|
|
* Calls audio power down
|
|
*/
|
|
static DRXStatus_t
|
|
PowerDownATV( pDRXDemodInstance_t demod , DRXStandard_t standard, Bool_t primary )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* *parameter */ NULL,
|
|
/* *result */ NULL };
|
|
u16_t cmdResult = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod->myExtAttr;
|
|
/* ATV NTSC */
|
|
|
|
/* Stop ATV SCU (will reset ATV and IQM hardware */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_STOP;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
/* Disable ATV outputs (ATV reset enables CVBS, undo this) */
|
|
WR16 ( devAddr, ATV_TOP_STDBY__A, ( ATV_TOP_STDBY_SIF_STDBY_STANDBY &
|
|
(~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) ) );
|
|
|
|
WR16( devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP);
|
|
if (primary == TRUE)
|
|
{
|
|
WR16( devAddr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP );
|
|
CHK_ERROR( SetIqmAf( demod, FALSE ) );
|
|
}
|
|
else
|
|
{
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
}
|
|
CHK_ERROR( PowerDownAud(demod) );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t SetATVStandard ()
|
|
* \brief Set up ATV demodulator.
|
|
* \param demod instance of demodulator
|
|
* \param standard either NTSC or FM (sub strandard for ATV )
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Init all channel independent registers.
|
|
* Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
|
|
*
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
#define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
|
|
static DRXStatus_t
|
|
SetATVStandard( pDRXDemodInstance_t demod , pDRXStandard_t standard )
|
|
{
|
|
/* TODO: enable alternative for tap settings via external file
|
|
|
|
something like:
|
|
#ifdef DRXJ_ATV_COEF_FILE
|
|
#include DRXJ_ATV_COEF_FILE
|
|
#else
|
|
... code defining fixed coef's ...
|
|
#endif
|
|
|
|
Cutsomer must create file "customer_coefs.c.inc" containing
|
|
modified copy off the constants below, and define the compiler
|
|
switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
|
|
|
|
Still to check if this will work; DRXJ_16TO8 macro may cause
|
|
trouble ?
|
|
*/
|
|
const u8_t ntsc_taps_re[]= {
|
|
DRXJ_16TO8(-12 ), /* re0 */
|
|
DRXJ_16TO8(-9 ), /* re1 */
|
|
DRXJ_16TO8( 9 ), /* re2 */
|
|
DRXJ_16TO8( 19 ), /* re3 */
|
|
DRXJ_16TO8(-4 ), /* re4 */
|
|
DRXJ_16TO8(-24 ), /* re5 */
|
|
DRXJ_16TO8(-6 ), /* re6 */
|
|
DRXJ_16TO8( 16 ), /* re7 */
|
|
DRXJ_16TO8( 6 ), /* re8 */
|
|
DRXJ_16TO8(-16 ), /* re9 */
|
|
DRXJ_16TO8(-5 ), /* re10 */
|
|
DRXJ_16TO8( 13 ), /* re11 */
|
|
DRXJ_16TO8(-2 ), /* re12 */
|
|
DRXJ_16TO8(-20 ), /* re13 */
|
|
DRXJ_16TO8( 4 ), /* re14 */
|
|
DRXJ_16TO8( 25 ), /* re15 */
|
|
DRXJ_16TO8(-6 ), /* re16 */
|
|
DRXJ_16TO8(-36 ), /* re17 */
|
|
DRXJ_16TO8( 2 ), /* re18 */
|
|
DRXJ_16TO8( 38 ), /* re19 */
|
|
DRXJ_16TO8(-10 ), /* re20 */
|
|
DRXJ_16TO8(-48 ), /* re21 */
|
|
DRXJ_16TO8( 35 ), /* re22 */
|
|
DRXJ_16TO8( 94 ), /* re23 */
|
|
DRXJ_16TO8(-59 ), /* re24 */
|
|
DRXJ_16TO8(-217 ), /* re25 */
|
|
DRXJ_16TO8( 50 ), /* re26 */
|
|
DRXJ_16TO8( 679 ) /* re27 */
|
|
};
|
|
const u8_t ntsc_taps_im[]= {
|
|
DRXJ_16TO8( 11 ), /* im0 */
|
|
DRXJ_16TO8( 1 ), /* im1 */
|
|
DRXJ_16TO8(-10 ), /* im2 */
|
|
DRXJ_16TO8( 2 ), /* im3 */
|
|
DRXJ_16TO8( 24 ), /* im4 */
|
|
DRXJ_16TO8( 21 ), /* im5 */
|
|
DRXJ_16TO8( 1 ), /* im6 */
|
|
DRXJ_16TO8(-4 ), /* im7 */
|
|
DRXJ_16TO8( 7 ), /* im8 */
|
|
DRXJ_16TO8( 14 ), /* im9 */
|
|
DRXJ_16TO8( 27 ), /* im10 */
|
|
DRXJ_16TO8( 42 ), /* im11 */
|
|
DRXJ_16TO8( 22 ), /* im12 */
|
|
DRXJ_16TO8(-20 ), /* im13 */
|
|
DRXJ_16TO8( 2 ), /* im14 */
|
|
DRXJ_16TO8( 98 ), /* im15 */
|
|
DRXJ_16TO8( 122 ), /* im16 */
|
|
DRXJ_16TO8( 0 ), /* im17 */
|
|
DRXJ_16TO8(-85 ), /* im18 */
|
|
DRXJ_16TO8( 51 ), /* im19 */
|
|
DRXJ_16TO8( 247 ), /* im20 */
|
|
DRXJ_16TO8( 192 ), /* im21 */
|
|
DRXJ_16TO8(-55 ), /* im22 */
|
|
DRXJ_16TO8(-95 ), /* im23 */
|
|
DRXJ_16TO8( 217 ), /* im24 */
|
|
DRXJ_16TO8( 544 ), /* im25 */
|
|
DRXJ_16TO8( 553 ), /* im26 */
|
|
DRXJ_16TO8( 302 ) /* im27 */
|
|
};
|
|
const u8_t bg_taps_re[]= {
|
|
DRXJ_16TO8(-18 ), /* re0 */
|
|
DRXJ_16TO8( 18 ), /* re1 */
|
|
DRXJ_16TO8( 19 ), /* re2 */
|
|
DRXJ_16TO8(-26 ), /* re3 */
|
|
DRXJ_16TO8(-20 ), /* re4 */
|
|
DRXJ_16TO8( 36 ), /* re5 */
|
|
DRXJ_16TO8( 5 ), /* re6 */
|
|
DRXJ_16TO8(-51 ), /* re7 */
|
|
DRXJ_16TO8( 15 ), /* re8 */
|
|
DRXJ_16TO8( 45 ), /* re9 */
|
|
DRXJ_16TO8(-46 ), /* re10 */
|
|
DRXJ_16TO8(-24 ), /* re11 */
|
|
DRXJ_16TO8( 71 ), /* re12 */
|
|
DRXJ_16TO8(-17 ), /* re13 */
|
|
DRXJ_16TO8(-83 ), /* re14 */
|
|
DRXJ_16TO8( 74 ), /* re15 */
|
|
DRXJ_16TO8( 75 ), /* re16 */
|
|
DRXJ_16TO8(-134 ), /* re17 */
|
|
DRXJ_16TO8(-40 ), /* re18 */
|
|
DRXJ_16TO8( 191 ), /* re19 */
|
|
DRXJ_16TO8(-11 ), /* re20 */
|
|
DRXJ_16TO8(-233 ), /* re21 */
|
|
DRXJ_16TO8( 74 ), /* re22 */
|
|
DRXJ_16TO8( 271 ), /* re23 */
|
|
DRXJ_16TO8(-132 ), /* re24 */
|
|
DRXJ_16TO8(-341 ), /* re25 */
|
|
DRXJ_16TO8( 172 ), /* re26 */
|
|
DRXJ_16TO8( 801 ) /* re27 */
|
|
};
|
|
const u8_t bg_taps_im[]= {
|
|
DRXJ_16TO8(-24 ), /* im0 */
|
|
DRXJ_16TO8(-10 ), /* im1 */
|
|
DRXJ_16TO8( 9 ), /* im2 */
|
|
DRXJ_16TO8(-5 ), /* im3 */
|
|
DRXJ_16TO8(-51 ), /* im4 */
|
|
DRXJ_16TO8(-17 ), /* im5 */
|
|
DRXJ_16TO8( 31 ), /* im6 */
|
|
DRXJ_16TO8(-48 ), /* im7 */
|
|
DRXJ_16TO8(-95 ), /* im8 */
|
|
DRXJ_16TO8( 25 ), /* im9 */
|
|
DRXJ_16TO8( 37 ), /* im10 */
|
|
DRXJ_16TO8(-123 ), /* im11 */
|
|
DRXJ_16TO8(-77 ), /* im12 */
|
|
DRXJ_16TO8( 94 ), /* im13 */
|
|
DRXJ_16TO8(-10 ), /* im14 */
|
|
DRXJ_16TO8(-149 ), /* im15 */
|
|
DRXJ_16TO8( 10 ), /* im16 */
|
|
DRXJ_16TO8( 108 ), /* im17 */
|
|
DRXJ_16TO8(-49 ), /* im18 */
|
|
DRXJ_16TO8(-59 ), /* im19 */
|
|
DRXJ_16TO8( 90 ), /* im20 */
|
|
DRXJ_16TO8( 73 ), /* im21 */
|
|
DRXJ_16TO8( 55 ), /* im22 */
|
|
DRXJ_16TO8( 148 ), /* im23 */
|
|
DRXJ_16TO8( 86 ), /* im24 */
|
|
DRXJ_16TO8( 146 ), /* im25 */
|
|
DRXJ_16TO8( 687 ), /* im26 */
|
|
DRXJ_16TO8( 877 ) /* im27 */
|
|
};
|
|
const u8_t dk_i_l_lp_taps_re[]= {
|
|
DRXJ_16TO8(-23 ), /* re0 */
|
|
DRXJ_16TO8( 9 ), /* re1 */
|
|
DRXJ_16TO8( 16 ), /* re2 */
|
|
DRXJ_16TO8(-26 ), /* re3 */
|
|
DRXJ_16TO8(-3 ), /* re4 */
|
|
DRXJ_16TO8( 13 ), /* re5 */
|
|
DRXJ_16TO8(-19 ), /* re6 */
|
|
DRXJ_16TO8(-3 ), /* re7 */
|
|
DRXJ_16TO8( 13 ), /* re8 */
|
|
DRXJ_16TO8(-26 ), /* re9 */
|
|
DRXJ_16TO8(-4 ), /* re10 */
|
|
DRXJ_16TO8( 28 ), /* re11 */
|
|
DRXJ_16TO8(-15 ), /* re12 */
|
|
DRXJ_16TO8(-14 ), /* re13 */
|
|
DRXJ_16TO8( 10 ), /* re14 */
|
|
DRXJ_16TO8( 1 ), /* re15 */
|
|
DRXJ_16TO8( 39 ), /* re16 */
|
|
DRXJ_16TO8(-18 ), /* re17 */
|
|
DRXJ_16TO8(-90 ), /* re18 */
|
|
DRXJ_16TO8( 109 ), /* re19 */
|
|
DRXJ_16TO8( 113 ), /* re20 */
|
|
DRXJ_16TO8(-235 ), /* re21 */
|
|
DRXJ_16TO8(-49 ), /* re22 */
|
|
DRXJ_16TO8( 359 ), /* re23 */
|
|
DRXJ_16TO8(-79 ), /* re24 */
|
|
DRXJ_16TO8(-459 ), /* re25 */
|
|
DRXJ_16TO8( 206 ), /* re26 */
|
|
DRXJ_16TO8( 894 ) /* re27 */
|
|
};
|
|
const u8_t dk_i_l_lp_taps_im[]= {
|
|
DRXJ_16TO8(-8 ), /* im0 */
|
|
DRXJ_16TO8(-20 ), /* im1 */
|
|
DRXJ_16TO8( 17 ), /* im2 */
|
|
DRXJ_16TO8(-14 ), /* im3 */
|
|
DRXJ_16TO8(-52 ), /* im4 */
|
|
DRXJ_16TO8( 4 ), /* im5 */
|
|
DRXJ_16TO8( 9 ), /* im6 */
|
|
DRXJ_16TO8(-62 ), /* im7 */
|
|
DRXJ_16TO8(-47 ), /* im8 */
|
|
DRXJ_16TO8( 0 ), /* im9 */
|
|
DRXJ_16TO8(-20 ), /* im10 */
|
|
DRXJ_16TO8(-48 ), /* im11 */
|
|
DRXJ_16TO8(-65 ), /* im12 */
|
|
DRXJ_16TO8(-23 ), /* im13 */
|
|
DRXJ_16TO8( 44 ), /* im14 */
|
|
DRXJ_16TO8(-60 ), /* im15 */
|
|
DRXJ_16TO8(-113 ), /* im16 */
|
|
DRXJ_16TO8( 92 ), /* im17 */
|
|
DRXJ_16TO8( 81 ), /* im18 */
|
|
DRXJ_16TO8(-125 ), /* im19 */
|
|
DRXJ_16TO8( 28 ), /* im20 */
|
|
DRXJ_16TO8( 182 ), /* im21 */
|
|
DRXJ_16TO8( 35 ), /* im22 */
|
|
DRXJ_16TO8( 94 ), /* im23 */
|
|
DRXJ_16TO8( 180 ), /* im24 */
|
|
DRXJ_16TO8( 134 ), /* im25 */
|
|
DRXJ_16TO8( 657 ), /* im26 */
|
|
DRXJ_16TO8( 1023 ) /* im27 */
|
|
};
|
|
const u8_t fm_taps_re[]= {
|
|
DRXJ_16TO8( 0 ), /* re0 */
|
|
DRXJ_16TO8( 0 ), /* re1 */
|
|
DRXJ_16TO8( 0 ), /* re2 */
|
|
DRXJ_16TO8( 0 ), /* re3 */
|
|
DRXJ_16TO8( 0 ), /* re4 */
|
|
DRXJ_16TO8( 0 ), /* re5 */
|
|
DRXJ_16TO8( 0 ), /* re6 */
|
|
DRXJ_16TO8( 0 ), /* re7 */
|
|
DRXJ_16TO8( 0 ), /* re8 */
|
|
DRXJ_16TO8( 0 ), /* re9 */
|
|
DRXJ_16TO8( 0 ), /* re10 */
|
|
DRXJ_16TO8( 0 ), /* re11 */
|
|
DRXJ_16TO8( 0 ), /* re12 */
|
|
DRXJ_16TO8( 0 ), /* re13 */
|
|
DRXJ_16TO8( 0 ), /* re14 */
|
|
DRXJ_16TO8( 0 ), /* re15 */
|
|
DRXJ_16TO8( 0 ), /* re16 */
|
|
DRXJ_16TO8( 0 ), /* re17 */
|
|
DRXJ_16TO8( 0 ), /* re18 */
|
|
DRXJ_16TO8( 0 ), /* re19 */
|
|
DRXJ_16TO8( 0 ), /* re20 */
|
|
DRXJ_16TO8( 0 ), /* re21 */
|
|
DRXJ_16TO8( 0 ), /* re22 */
|
|
DRXJ_16TO8( 0 ), /* re23 */
|
|
DRXJ_16TO8( 0 ), /* re24 */
|
|
DRXJ_16TO8( 0 ), /* re25 */
|
|
DRXJ_16TO8( 0 ), /* re26 */
|
|
DRXJ_16TO8( 0 ) /* re27 */
|
|
};
|
|
const u8_t fm_taps_im[]= {
|
|
DRXJ_16TO8(-6 ), /* im0 */
|
|
DRXJ_16TO8( 2 ), /* im1 */
|
|
DRXJ_16TO8( 14 ), /* im2 */
|
|
DRXJ_16TO8(-38 ), /* im3 */
|
|
DRXJ_16TO8( 58 ), /* im4 */
|
|
DRXJ_16TO8(-62 ), /* im5 */
|
|
DRXJ_16TO8( 42 ), /* im6 */
|
|
DRXJ_16TO8( 0 ), /* im7 */
|
|
DRXJ_16TO8(-45 ), /* im8 */
|
|
DRXJ_16TO8( 73 ), /* im9 */
|
|
DRXJ_16TO8(-65 ), /* im10 */
|
|
DRXJ_16TO8( 23 ), /* im11 */
|
|
DRXJ_16TO8( 34 ), /* im12 */
|
|
DRXJ_16TO8(-77 ), /* im13 */
|
|
DRXJ_16TO8( 80 ), /* im14 */
|
|
DRXJ_16TO8(-39 ), /* im15 */
|
|
DRXJ_16TO8(-25 ), /* im16 */
|
|
DRXJ_16TO8( 78 ), /* im17 */
|
|
DRXJ_16TO8(-90 ), /* im18 */
|
|
DRXJ_16TO8( 52 ), /* im19 */
|
|
DRXJ_16TO8( 16 ), /* im20 */
|
|
DRXJ_16TO8(-77 ), /* im21 */
|
|
DRXJ_16TO8( 97 ), /* im22 */
|
|
DRXJ_16TO8(-62 ), /* im23 */
|
|
DRXJ_16TO8(-8 ), /* im24 */
|
|
DRXJ_16TO8( 75 ), /* im25 */
|
|
DRXJ_16TO8(-100 ), /* im26 */
|
|
DRXJ_16TO8( 70 ) /* im27 */
|
|
};
|
|
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* *parameter */ NULL,
|
|
/* *result */ NULL };
|
|
u16_t cmdResult = 0;
|
|
u16_t cmdParam = 0;
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
DRXUCodeInfo_t ucodeInfo;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
commonAttr = demod -> myCommonAttr;
|
|
|
|
/* Check if audio microcode is already uploaded */
|
|
if ( !( extAttr->flagAudMcUploaded ) )
|
|
{
|
|
ucodeInfo.mcData = commonAttr->microcode;
|
|
ucodeInfo.mcSize = commonAttr->microcodeSize;
|
|
|
|
/* Upload only audio microcode */
|
|
CHK_ERROR ( CtrlUCodeUpload( demod, &ucodeInfo, UCODE_UPLOAD, TRUE ) );
|
|
|
|
if ( commonAttr->verifyMicrocode == TRUE )
|
|
{
|
|
CHK_ERROR( CtrlUCodeUpload( demod, &ucodeInfo, UCODE_VERIFY, TRUE ) );
|
|
}
|
|
|
|
/* Prevent uploading audio microcode again */
|
|
extAttr->flagAudMcUploaded = TRUE;
|
|
}
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
WR16( devAddr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP );
|
|
WR16( devAddr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP );
|
|
/* Reset ATV SCU */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_RESET;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
WR16( devAddr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE );
|
|
|
|
/* TODO remove AUTO/OFF patches after ucode fix. */
|
|
switch ( *standard )
|
|
{
|
|
case DRX_STANDARD_NTSC:
|
|
/* NTSC */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_MN;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , IQM_RT_LO_INCR_MN );
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(ntsc_taps_re) ,
|
|
((pu8_t)ntsc_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(ntsc_taps_im) ,
|
|
((pu8_t)ntsc_taps_im) );
|
|
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A , ATV_TOP_CR_AMP_TH_MN );
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_MN |
|
|
ATV_TOP_CR_CONT_CR_D_MN |
|
|
ATV_TOP_CR_CONT_CR_I_MN ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_MN );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_MN |
|
|
ATV_TOP_STD_VID_POL_MN ) );
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_MN );
|
|
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
|
|
SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
/* FM */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_FM;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 2994 );
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , 0 );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(fm_taps_re) ,
|
|
((pu8_t)fm_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(fm_taps_im) ,
|
|
((pu8_t)fm_taps_im) );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_FM |
|
|
ATV_TOP_STD_VID_POL_FM ) );
|
|
WR16( devAddr, ATV_TOP_MOD_CONTROL__A, 0 );
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A , 0 );
|
|
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW |
|
|
SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM ));
|
|
WR16( devAddr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF );
|
|
extAttr->phaseCorrectionBypass = TRUE;
|
|
extAttr->enableCVBSOutput = FALSE;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
/* PAL/SECAM B/G */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_B;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 1820 );/* TODO check with IS */
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(bg_taps_re) ,
|
|
((pu8_t)bg_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(bg_taps_im) ,
|
|
((pu8_t)bg_taps_im) );
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_BG );
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG );
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_BG |
|
|
ATV_TOP_CR_CONT_CR_D_BG |
|
|
ATV_TOP_CR_CONT_CR_I_BG ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_BG );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_BG |
|
|
ATV_TOP_STD_VID_POL_BG ) );
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
|
|
SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
/* PAL/SECAM D/K */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_DK;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 2225 );/* TODO check with IS */
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(dk_i_l_lp_taps_re) ,
|
|
((pu8_t)dk_i_l_lp_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(dk_i_l_lp_taps_im) ,
|
|
((pu8_t)dk_i_l_lp_taps_im) );
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A , ATV_TOP_CR_AMP_TH_DK );
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_DK );
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_DK |
|
|
ATV_TOP_CR_CONT_CR_D_DK |
|
|
ATV_TOP_CR_CONT_CR_I_DK ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_DK );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_DK |
|
|
ATV_TOP_STD_VID_POL_DK ) );
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
|
|
SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->atvIfAgcCfg.ctrlMode =DRX_AGC_CTRL_AUTO;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
/* PAL/SECAM I */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_I;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 2225 );/* TODO check with IS */
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(dk_i_l_lp_taps_re) ,
|
|
((pu8_t)dk_i_l_lp_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(dk_i_l_lp_taps_im) ,
|
|
((pu8_t)dk_i_l_lp_taps_im) );
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A , ATV_TOP_CR_AMP_TH_I );
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_I );
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_I |
|
|
ATV_TOP_CR_CONT_CR_D_I |
|
|
ATV_TOP_CR_CONT_CR_I_I ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_I );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_I |
|
|
ATV_TOP_STD_VID_POL_I ) );
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
|
|
SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
/* PAL/SECAM L with negative modulation */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_L;
|
|
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 2225 ); /* TODO check with IS */
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_L );
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(dk_i_l_lp_taps_re) ,
|
|
((pu8_t)dk_i_l_lp_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(dk_i_l_lp_taps_im) ,
|
|
((pu8_t)dk_i_l_lp_taps_im) );
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A , 0x2 ); /* TODO check with IS */
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_L |
|
|
ATV_TOP_CR_CONT_CR_D_L |
|
|
ATV_TOP_CR_CONT_CR_I_L ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_L );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_L |
|
|
ATV_TOP_STD_VID_POL_L ) );
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
|
|
SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
|
|
SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_USER;
|
|
extAttr->atvIfAgcCfg.outputLevel = extAttr->atvRfAgcCfg.top;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
/* PAL/SECAM L with positive modulation */
|
|
cmdParam = SCU_RAM_ATV_STANDARD_STANDARD_LP;
|
|
|
|
WR16( devAddr, ATV_TOP_VID_AMP__A , ATV_TOP_VID_AMP_LP );
|
|
WR16( devAddr, IQM_RT_LO_INCR__A , 2225 ); /* TODO check with IS */
|
|
WR16( devAddr, IQM_CF_MIDTAP__A , IQM_CF_MIDTAP_RE__M );
|
|
WRB ( devAddr, IQM_CF_TAP_RE0__A , sizeof(dk_i_l_lp_taps_re) ,
|
|
((pu8_t)dk_i_l_lp_taps_re) );
|
|
WRB ( devAddr, IQM_CF_TAP_IM0__A , sizeof(dk_i_l_lp_taps_im) ,
|
|
((pu8_t)dk_i_l_lp_taps_im) );
|
|
WR16( devAddr, ATV_TOP_CR_AMP_TH__A , 0x2 ); /* TODO check with IS */
|
|
WR16( devAddr, ATV_TOP_CR_CONT__A ,
|
|
( ATV_TOP_CR_CONT_CR_P_LP |
|
|
ATV_TOP_CR_CONT_CR_D_LP |
|
|
ATV_TOP_CR_CONT_CR_I_LP ) );
|
|
WR16( devAddr, ATV_TOP_CR_OVM_TH__A , ATV_TOP_CR_OVM_TH_LP );
|
|
WR16( devAddr, ATV_TOP_STD__A , (ATV_TOP_STD_MODE_LP |
|
|
ATV_TOP_STD_VID_POL_LP ) );
|
|
WR16( devAddr, SCU_RAM_ATV_AGC_MODE__A ,
|
|
( SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
|
|
SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
|
|
SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW ) );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000 );
|
|
WR16( devAddr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX_REF__A,
|
|
SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
|
|
extAttr->phaseCorrectionBypass = FALSE;
|
|
extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_USER;
|
|
extAttr->atvIfAgcCfg.outputLevel = extAttr->atvRfAgcCfg.top;
|
|
extAttr->enableCVBSOutput = TRUE;
|
|
break;
|
|
default:
|
|
return ( DRX_STS_ERROR );
|
|
}
|
|
|
|
/* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
|
|
if (extAttr->hasLNA == FALSE)
|
|
{
|
|
WR16( devAddr, IQM_AF_AMUX__A, 0x01);
|
|
}
|
|
|
|
WR16( devAddr, SCU_RAM_ATV_STANDARD__A , 0x002 );
|
|
WR16( devAddr, IQM_AF_CLP_LEN__A , IQM_AF_CLP_LEN_ATV );
|
|
WR16( devAddr, IQM_AF_CLP_TH__A , IQM_AF_CLP_TH_ATV );
|
|
WR16( devAddr, IQM_AF_SNS_LEN__A , IQM_AF_SNS_LEN_ATV );
|
|
CHK_ERROR( CtrlSetCfgPreSaw( demod, &(extAttr->atvPreSawCfg)) );
|
|
WR16( devAddr, IQM_AF_AGC_IF__A , 10248 );
|
|
|
|
extAttr->iqmRcRateOfs = 0x00200000L;
|
|
WR32( devAddr, IQM_RC_RATE_OFS_LO__A , extAttr->iqmRcRateOfs );
|
|
WR16( devAddr, IQM_RC_ADJ_SEL__A , IQM_RC_ADJ_SEL_B_OFF );
|
|
WR16( devAddr, IQM_RC_STRETCH__A , IQM_RC_STRETCH_ATV );
|
|
|
|
WR16( devAddr, IQM_RT_ACTIVE__A , IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON |
|
|
IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON );
|
|
|
|
WR16( devAddr, IQM_CF_OUT_ENA__A , IQM_CF_OUT_ENA_ATV__M );
|
|
WR16( devAddr, IQM_CF_SYMMETRIC__A , IQM_CF_SYMMETRIC_IM__M );
|
|
/* default: SIF in standby */
|
|
WR16( devAddr, ATV_TOP_SYNC_SLICE__A , ATV_TOP_SYNC_SLICE_MN );
|
|
WR16( devAddr, ATV_TOP_MOD_ACCU__A , ATV_TOP_MOD_ACCU__PRE );
|
|
|
|
WR16( devAddr, SCU_RAM_ATV_SIF_GAIN__A , 0x080 );
|
|
WR16( devAddr, SCU_RAM_ATV_FAGC_TH_RED__A , 10 );
|
|
WR16( devAddr, SCU_RAM_ATV_AAGC_CNT__A , 7 );
|
|
WR16( devAddr, SCU_RAM_ATV_NAGC_KI_MIN__A , 0x0225 );
|
|
WR16( devAddr, SCU_RAM_ATV_NAGC_KI_MAX__A , 0x0547 );
|
|
WR16( devAddr, SCU_RAM_ATV_KI_CHANGE_TH__A , 20 );
|
|
WR16( devAddr, SCU_RAM_ATV_LOCK__A , 0 );
|
|
|
|
WR16( devAddr, IQM_RT_DELAY__A , IQM_RT_DELAY__PRE );
|
|
WR16( devAddr, SCU_RAM_ATV_BPC_KI_MIN__A , 531 );
|
|
WR16( devAddr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061 );
|
|
WR16( devAddr, SCU_RAM_ATV_BP_REF_MIN__A , 100 );
|
|
WR16( devAddr, SCU_RAM_ATV_BP_REF_MAX__A , 260 );
|
|
WR16( devAddr, SCU_RAM_ATV_BP_LVL__A , 0 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MAX__A , 0 );
|
|
WR16( devAddr, SCU_RAM_ATV_AMS_MIN__A , 2047 );
|
|
WR16( devAddr, SCU_RAM_GPIO__A , 0 );
|
|
|
|
/* Override reset values with current shadow settings */
|
|
CHK_ERROR( AtvUpdateConfig( demod, TRUE) );
|
|
|
|
/* Configure/restore AGC settings */
|
|
CHK_ERROR( InitAGC( demod ) );
|
|
CHK_ERROR( SetAgcIf( demod, &(extAttr->atvIfAgcCfg), FALSE ) );
|
|
CHK_ERROR( SetAgcRf( demod, &(extAttr->atvRfAgcCfg), FALSE ) );
|
|
CHK_ERROR( CtrlSetCfgPreSaw( demod, &(extAttr->atvPreSawCfg)) );
|
|
|
|
/* Set SCU ATV substandard,assuming this doesn't require running ATV block */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
|
|
cmdSCU.parameterLen = 1;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = &cmdParam;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
/* turn the analog work around on/off (must after set_env b/c it is set in mc)*/
|
|
if ( extAttr->mfx == 0x03 )
|
|
{
|
|
WR16( devAddr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0 );
|
|
}
|
|
else
|
|
{
|
|
WR16( devAddr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1 );
|
|
WR16( devAddr, SCU_RAM_ATV_IIR_CRIT__A , 225 );
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
/**
|
|
* \fn DRXStatus_t SetATVChannel ()
|
|
* \brief Set ATV channel.
|
|
* \param demod: instance of demod.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Not much needs to be done here, only start the SCU for NTSC/FM.
|
|
* Mirrored channels are not expected in the RF domain, so IQM FS setting
|
|
* doesn't need to be remembered.
|
|
* The channel->mirror parameter is therefor ignored.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
SetATVChannel( pDRXDemodInstance_t demod,
|
|
DRXFrequency_t tunerFreqOffset,
|
|
pDRXChannel_t channel,
|
|
DRXStandard_t standard )
|
|
{
|
|
DRXJSCUCmd_t cmdSCU = {/* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* parameter */ NULL,
|
|
/* result */ NULL };
|
|
u16_t cmdResult = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/*
|
|
Program frequency shifter
|
|
No need to account for mirroring on RF
|
|
*/
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
|
|
CHK_ERROR ( SetFrequency ( demod, channel, tunerFreqOffset ) );
|
|
WR16(devAddr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE);
|
|
|
|
/* Start ATV SCU */
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_START;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 1;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = &cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
/* if ( (extAttr->standard == DRX_STANDARD_FM) && (extAttr->flagSetAUDdone == TRUE) )
|
|
{
|
|
extAttr->detectedRDS = (Bool_t)FALSE;
|
|
}*/
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetATVChannel ()
|
|
* \brief Set ATV channel.
|
|
* \param demod: instance of demod.
|
|
* \param channel: pointer to channel data.
|
|
* \param standard: NTSC or FM.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
|
|
* Computes the frequency offset in te RF domain and adds it to
|
|
* channel->frequency. Determines the value for channel->bandwidth.
|
|
*
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
GetATVChannel( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel,
|
|
DRXStandard_t standard )
|
|
{
|
|
DRXFrequency_t offset = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* Bandwidth */
|
|
channel->bandwidth = ((pDRXJData_t)demod -> myExtAttr)->currBandwidth;
|
|
|
|
switch ( standard )
|
|
{
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
{
|
|
u16_t measuredOffset=0;
|
|
|
|
/* get measured frequency offset */
|
|
RR16(devAddr, ATV_TOP_CR_FREQ__A, &measuredOffset);
|
|
/* Signed 8 bit register => sign extension needed */
|
|
if ( (measuredOffset & 0x0080) != 0)
|
|
{
|
|
/* sign extension */
|
|
measuredOffset |= 0xFF80;
|
|
}
|
|
offset+= (DRXFrequency_t)( ((s16_t)measuredOffset)*10);
|
|
break;
|
|
}
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
{
|
|
u16_t measuredOffset=0;
|
|
|
|
/* get measured frequency offset */
|
|
RR16(devAddr, ATV_TOP_CR_FREQ__A, &measuredOffset);
|
|
/* Signed 8 bit register => sign extension needed */
|
|
if ( (measuredOffset & 0x0080) != 0)
|
|
{
|
|
/* sign extension */
|
|
measuredOffset |= 0xFF80;
|
|
}
|
|
offset-= (DRXFrequency_t)( ((s16_t)measuredOffset)*10);
|
|
}
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
/* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
|
|
AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
|
|
*/
|
|
/* No bandwidth know for FM */
|
|
channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
|
|
break;
|
|
default:
|
|
return ( DRX_STS_ERROR );
|
|
}
|
|
|
|
channel->frequency -= offset;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t GetAtvSigStrength()
|
|
* \brief Retrieve signal strength for ATV & FM.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param sigQuality Pointer to signal strength data; range 0, .. , 100.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigStrength contains valid data.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigStrength equals 0.
|
|
*
|
|
* Taking into account:
|
|
* * digital gain
|
|
* * IF gain (not implemented yet, waiting for IF gain control by ucode)
|
|
* * RF gain
|
|
*
|
|
* All weights (digital, if, rf) must add up to 100.
|
|
*
|
|
* TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
|
|
* is not used ?
|
|
*/
|
|
static DRXStatus_t
|
|
GetAtvSigStrength( pDRXDemodInstance_t demod,
|
|
pu16_t sigStrength )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* All weights must add up to 100 (%)
|
|
TODO: change weights when IF ctrl is available */
|
|
u32_t digitalWeight = 50; /* 0 .. 100 */
|
|
u32_t rfWeight = 50; /* 0 .. 100 */
|
|
u32_t ifWeight = 0; /* 0 .. 100 */
|
|
|
|
u16_t digitalCurrGain = 0;
|
|
u32_t digitalMaxGain = 0;
|
|
u32_t digitalMinGain = 0;
|
|
u16_t rfCurrGain = 0;
|
|
u32_t rfMaxGain = 0x800; /* taken from ucode */
|
|
u32_t rfMinGain = 0x7fff;
|
|
u16_t ifCurrGain = 0;
|
|
u32_t ifMaxGain = 0x800; /* taken from ucode */
|
|
u32_t ifMinGain = 0x7fff;
|
|
|
|
u32_t digitalStrength = 0; /* 0.. 100 */
|
|
u32_t rfStrength = 0; /* 0.. 100 */
|
|
u32_t ifStrength = 0; /* 0.. 100 */
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
*sigStrength = 0;
|
|
|
|
switch( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC:
|
|
SARR16(devAddr, SCU_RAM_ATV_VID_GAIN_HI__A, &digitalCurrGain);
|
|
digitalMaxGain = 22512; /* taken from ucode */
|
|
digitalMinGain = 2400; /* taken from ucode */
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
SARR16(devAddr, SCU_RAM_ATV_SIF_GAIN__A, &digitalCurrGain);
|
|
digitalMaxGain = 0x4ff; /* taken from ucode */
|
|
digitalMinGain = 0; /* taken from ucode */
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
break;
|
|
}
|
|
RR16(devAddr, IQM_AF_AGC_RF__A, &rfCurrGain);
|
|
RR16(devAddr, IQM_AF_AGC_IF__A, &ifCurrGain);
|
|
|
|
/* clipping */
|
|
if ( digitalCurrGain >= digitalMaxGain ) digitalCurrGain = (u16_t)digitalMaxGain;
|
|
if ( digitalCurrGain <= digitalMinGain ) digitalCurrGain = (u16_t)digitalMinGain;
|
|
if ( ifCurrGain <= ifMaxGain ) ifCurrGain = (u16_t)ifMaxGain;
|
|
if ( ifCurrGain >= ifMinGain ) ifCurrGain = (u16_t)ifMinGain;
|
|
if ( rfCurrGain <= rfMaxGain ) rfCurrGain = (u16_t)rfMaxGain;
|
|
if ( rfCurrGain >= rfMinGain ) rfCurrGain = (u16_t)rfMinGain;
|
|
|
|
/* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
|
|
of clipping at ADC */
|
|
|
|
/* Compute signal strength (in %) per "gain domain" */
|
|
|
|
/* Digital gain */
|
|
/* TODO: ADC clipping not handled */
|
|
digitalStrength = ( 100 *(digitalMaxGain-(u32_t)digitalCurrGain) )/
|
|
(digitalMaxGain -digitalMinGain);
|
|
|
|
/* TODO: IF gain not implemented yet in microcode, check after impl. */
|
|
ifStrength = ( 100 *((u32_t)ifCurrGain-ifMaxGain) )/
|
|
( ifMinGain - ifMaxGain );
|
|
|
|
/* Rf gain */
|
|
/* TODO: ADC clipping not handled */
|
|
rfStrength = ( 100 *((u32_t)rfCurrGain-rfMaxGain) )/
|
|
( rfMinGain - rfMaxGain );
|
|
|
|
/* Compute a weighted signal strength (in %) */
|
|
*sigStrength = (u16_t) (digitalWeight*digitalStrength +
|
|
rfWeight*rfStrength +
|
|
ifWeight*ifStrength);
|
|
*sigStrength /= 100;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/**
|
|
* \fn DRXStatus_t AtvSigQuality()
|
|
* \brief Retrieve signal quality indication for ATV.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param sigQuality Pointer to signal quality structure.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigQuality contains valid data.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigQuality indicator equals 0.
|
|
*
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AtvSigQuality( pDRXDemodInstance_t demod,
|
|
pDRXSigQuality_t sigQuality )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
u16_t qualityIndicator = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* defined values for fields not used */
|
|
sigQuality->MER = 0;
|
|
sigQuality->preViterbiBER = 0;
|
|
sigQuality->postViterbiBER = 0;
|
|
sigQuality->scaleFactorBER = 1;
|
|
sigQuality->packetError = 0;
|
|
sigQuality->postReedSolomonBER = 0;
|
|
|
|
/*
|
|
Mapping:
|
|
0x000..0x080: strong signal => 80% .. 100%
|
|
0x080..0x700: weak signal => 30% .. 80%
|
|
0x700..0x7ff: no signal => 0% .. 30%
|
|
*/
|
|
|
|
SARR16( devAddr, SCU_RAM_ATV_CR_LOCK__A, &qualityIndicator );
|
|
qualityIndicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
|
|
if ( qualityIndicator <= 0x80 )
|
|
{
|
|
sigQuality->indicator = 80 + ( (20*(0x80-qualityIndicator))/0x80);
|
|
} else if ( qualityIndicator <= 0x700 )
|
|
{
|
|
sigQuality->indicator = 30 +
|
|
( (50*(0x700-qualityIndicator))/(0x700-0x81));
|
|
} else {
|
|
sigQuality->indicator =
|
|
(30*(0x7FF-qualityIndicator))/(0x7FF-0x701);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif /* DRXJ_DIGITAL_ONLY */
|
|
|
|
/*============================================================================*/
|
|
/*== END ATV DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
#ifndef DRXJ_EXCLUDE_AUDIO
|
|
/*===========================================================================*/
|
|
/*===========================================================================*/
|
|
/*== AUDIO DATAPATH FUNCTIONS ==*/
|
|
/*===========================================================================*/
|
|
/*===========================================================================*/
|
|
|
|
/*
|
|
* \brief Power up AUD.
|
|
* \param demod instance of demodulator
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
PowerUpAud( pDRXDemodInstance_t demod,
|
|
Bool_t setStandard)
|
|
{
|
|
DRXAudStandard_t audStandard = DRX_AUD_STANDARD_AUTO;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
|
|
WR16( devAddr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE);
|
|
/* setup TR interface: R/W mode, fifosize=8 */
|
|
WR16( devAddr, AUD_TOP_TR_MDE__A, 8);
|
|
WR16( devAddr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE);
|
|
|
|
if ( setStandard == TRUE )
|
|
{
|
|
CHK_ERROR( AUDCtrlSetStandard ( demod, &audStandard ) );
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \brief Power up AUD.
|
|
* \param demod instance of demodulator
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
PowerDownAud( pDRXDemodInstance_t demod )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
WR16( devAddr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP );
|
|
|
|
extAttr->audData.audioIsActive = FALSE;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get Modus data from audio RAM
|
|
* \param demod instance of demodulator
|
|
* \param pointer to modus
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDGetModus ( pDRXDemodInstance_t demod,
|
|
pu16_t modus )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t rModus = 0;
|
|
u16_t rModusHi = 0;
|
|
u16_t rModusLo = 0;
|
|
|
|
if ( modus == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* Modus register is combined in to RAM location */
|
|
RR16( devAddr, AUD_DEM_RAM_MODUS_HI__A, &rModusHi );
|
|
RR16( devAddr, AUD_DEM_RAM_MODUS_LO__A, &rModusLo );
|
|
|
|
rModus = ( (rModusHi << 12 ) & AUD_DEM_RAM_MODUS_HI__M)
|
|
| ((( rModusLo & AUD_DEM_RAM_MODUS_LO__M) ));
|
|
|
|
*modus = rModus;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get audio RDS dat
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudRDS_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgRDS ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudRDS_t status )
|
|
{
|
|
pI2CDeviceAddr_t addr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t rRDSArrayCntInit = 0;
|
|
u16_t rRDSArrayCntCheck = 0;
|
|
u16_t rRDSData = 0;
|
|
u16_t RDSDataCnt = 0;
|
|
|
|
addr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
|
|
if ( status == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
status->valid = FALSE;
|
|
|
|
RR16( addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &rRDSArrayCntInit);
|
|
|
|
if ( rRDSArrayCntInit ==
|
|
AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID )
|
|
{
|
|
/* invalid data */
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
if ( extAttr->audData.rdsDataCounter == rRDSArrayCntInit)
|
|
{
|
|
/* no new data */
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/* RDS is detected, as long as FM radio is selected assume
|
|
RDS will be available */
|
|
extAttr->audData.rdsDataPresent = TRUE;
|
|
|
|
/* new data */
|
|
/* read the data */
|
|
for ( RDSDataCnt = 0;
|
|
RDSDataCnt < AUD_RDS_ARRAY_SIZE;
|
|
RDSDataCnt++)
|
|
{
|
|
RR16 ( addr, AUD_DEM_RD_RDS_DATA__A, &rRDSData );
|
|
status->data[RDSDataCnt] = rRDSData;
|
|
}
|
|
|
|
RR16( addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &rRDSArrayCntCheck);
|
|
|
|
if ( rRDSArrayCntCheck == rRDSArrayCntInit )
|
|
{
|
|
status->valid = TRUE;
|
|
extAttr->audData.rdsDataCounter = rRDSArrayCntCheck;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the current audio carrier detection status
|
|
* \param demod instance of demodulator
|
|
* \param pointer to AUDCtrlGetStatus
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCarrierDetectStatus ( pDRXDemodInstance_t demod,
|
|
pDRXAudStatus_t status )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
u16_t rData = 0;
|
|
|
|
if ( status == NULL)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* initialize the variables */
|
|
status->carrierA = FALSE;
|
|
status->carrierB = FALSE;
|
|
status->nicamStatus = DRX_AUD_NICAM_NOT_DETECTED;
|
|
status->sap = FALSE;
|
|
status->stereo = FALSE;
|
|
|
|
/* read stereo sound mode indication */
|
|
RR16( devAddr, AUD_DEM_RD_STATUS__A, &rData );
|
|
|
|
/* carrier a detected */
|
|
if ( (rData & AUD_DEM_RD_STATUS_STAT_CARR_A__M ) ==
|
|
AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED )
|
|
{
|
|
status->carrierA = TRUE;
|
|
}
|
|
|
|
/* carrier b detected */
|
|
if ( (rData & AUD_DEM_RD_STATUS_STAT_CARR_B__M ) ==
|
|
AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED )
|
|
{
|
|
status->carrierB = TRUE;
|
|
}
|
|
/* nicam detected */
|
|
if ( (rData & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
|
|
AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED)
|
|
{
|
|
if ((rData & AUD_DEM_RD_STATUS_BAD_NICAM__M) ==
|
|
AUD_DEM_RD_STATUS_BAD_NICAM_OK)
|
|
{
|
|
status->nicamStatus = DRX_AUD_NICAM_DETECTED;
|
|
}
|
|
else
|
|
{
|
|
status->nicamStatus = DRX_AUD_NICAM_BAD;
|
|
}
|
|
}
|
|
|
|
/* audio mode bilingual or SAP detected */
|
|
if ( (rData & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) ==
|
|
AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
|
|
{
|
|
status->sap = TRUE;
|
|
}
|
|
|
|
/* stereo detected */
|
|
if ( (rData & AUD_DEM_RD_STATUS_STAT_STEREO__M) ==
|
|
AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
|
|
{
|
|
status->stereo = TRUE;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the current audio status parameters
|
|
* \param demod instance of demodulator
|
|
* \param pointer to AUDCtrlGetStatus
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetStatus ( pDRXDemodInstance_t demod,
|
|
pDRXAudStatus_t status )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXCfgAudRDS_t rds = { FALSE, {0} };
|
|
u16_t rData = 0;
|
|
|
|
if ( status == NULL)
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* carrier detection */
|
|
CHK_ERROR ( AUDCtrlGetCarrierDetectStatus ( demod, status ) );
|
|
|
|
/* rds data */
|
|
status->rds = FALSE;
|
|
CHK_ERROR ( AUDCtrlGetCfgRDS ( demod, &rds ) );
|
|
status->rds = extAttr->audData.rdsDataPresent;
|
|
|
|
/* fmIdent */
|
|
RR16( devAddr, AUD_DSP_RD_FM_IDENT_VALUE__A, &rData);
|
|
rData >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
|
|
status->fmIdent = (s8_t)rData;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the current volume settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudVolume_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgVolume ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudVolume_t volume )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t rVolume = 0;
|
|
u16_t rAVC = 0;
|
|
u16_t rStrengthLeft = 0;
|
|
u16_t rStrengthRight = 0;
|
|
|
|
if ( volume == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* volume */
|
|
volume->mute = extAttr->audData.volume.mute;
|
|
RR16( devAddr, AUD_DSP_WR_VOLUME__A, &rVolume );
|
|
if ( rVolume == 0 )
|
|
{
|
|
volume->mute = TRUE;
|
|
volume->volume = extAttr->audData.volume.volume;
|
|
}
|
|
else
|
|
{
|
|
volume->mute = FALSE;
|
|
volume->volume = ( ( rVolume & AUD_DSP_WR_VOLUME_VOL_MAIN__M ) >>
|
|
AUD_DSP_WR_VOLUME_VOL_MAIN__B ) -
|
|
AUD_VOLUME_ZERO_DB;
|
|
if ( volume->volume < AUD_VOLUME_DB_MIN )
|
|
{
|
|
volume->volume = AUD_VOLUME_DB_MIN;
|
|
}
|
|
if ( volume->volume > AUD_VOLUME_DB_MAX )
|
|
{
|
|
volume->volume = AUD_VOLUME_DB_MAX;
|
|
}
|
|
}
|
|
|
|
/* automatic volume control */
|
|
RR16( devAddr, AUD_DSP_WR_AVC__A, &rAVC );
|
|
|
|
if( ( rAVC & AUD_DSP_WR_AVC_AVC_ON__M) ==
|
|
AUD_DSP_WR_AVC_AVC_ON_OFF )
|
|
|
|
{
|
|
volume->avcMode = DRX_AUD_AVC_OFF;
|
|
}
|
|
else
|
|
{
|
|
switch ( rAVC & AUD_DSP_WR_AVC_AVC_DECAY__M )
|
|
{
|
|
case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
|
|
volume->avcMode = DRX_AUD_AVC_DECAYTIME_20MS;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
|
|
volume->avcMode = DRX_AUD_AVC_DECAYTIME_8S;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
|
|
volume->avcMode = DRX_AUD_AVC_DECAYTIME_4S;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
|
|
volume->avcMode = DRX_AUD_AVC_DECAYTIME_2S;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* max attenuation */
|
|
switch ( rAVC & AUD_DSP_WR_AVC_AVC_MAX_ATT__M )
|
|
{
|
|
case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
|
|
volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_12DB;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
|
|
volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_18DB;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
|
|
volume->avcMaxAtten = DRX_AUD_AVC_MAX_ATTEN_24DB;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
/* max gain */
|
|
switch ( rAVC & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M )
|
|
{
|
|
case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
|
|
volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_0DB;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
|
|
volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_6DB;
|
|
break;
|
|
case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
|
|
volume->avcMaxGain = DRX_AUD_AVC_MAX_GAIN_12DB;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
/* reference level */
|
|
volume->avcRefLevel = (u16_t)( ( rAVC & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
|
|
AUD_DSP_WR_AVC_AVC_REF_LEV__B );
|
|
|
|
/* read qpeak registers and calculate strength of left and right carrier */
|
|
/* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
|
|
/* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
|
|
/* left carrier */
|
|
|
|
/* QP vaues */
|
|
/* left carrier */
|
|
RR16 (devAddr, AUD_DSP_RD_QPEAK_L__A, &rStrengthLeft);
|
|
volume->strengthLeft = ( ( (s16_t) Log10Times100 ( rStrengthLeft ) ) -
|
|
AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 ) / 5;
|
|
|
|
/* right carrier */
|
|
RR16 (devAddr, AUD_DSP_RD_QPEAK_R__A, &rStrengthRight);
|
|
volume->strengthRight = ( ( (s16_t) Log10Times100 ( rStrengthRight ) ) -
|
|
AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 ) / 5;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set the current volume settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudVolume_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgVolume ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudVolume_t volume )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t wVolume = 0;
|
|
u16_t wAVC = 0;
|
|
|
|
|
|
if ( volume == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* volume */
|
|
/* volume range from -60 to 12 (expressed in dB) */
|
|
if ( ( volume->volume < AUD_VOLUME_DB_MIN ) ||
|
|
( volume->volume > AUD_VOLUME_DB_MAX ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
RR16( devAddr, AUD_DSP_WR_VOLUME__A, &wVolume );
|
|
|
|
/* clear the volume mask */
|
|
wVolume &= (u16_t)~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
|
|
if ( volume->mute == TRUE )
|
|
{
|
|
/* mute */
|
|
/* mute overrules volume */
|
|
wVolume |= (u16_t) ( 0 );
|
|
|
|
}
|
|
else
|
|
{
|
|
wVolume |= (u16_t) ( ( volume->volume + AUD_VOLUME_ZERO_DB ) <<
|
|
AUD_DSP_WR_VOLUME_VOL_MAIN__B );
|
|
}
|
|
|
|
WR16( devAddr, AUD_DSP_WR_VOLUME__A, wVolume );
|
|
|
|
/* automatic volume control */
|
|
RR16( devAddr, AUD_DSP_WR_AVC__A, &wAVC );
|
|
|
|
/* clear masks that require writing */
|
|
wAVC &= (u16_t) ~AUD_DSP_WR_AVC_AVC_ON__M;
|
|
wAVC &= (u16_t) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
|
|
|
|
if ( volume->avcMode == DRX_AUD_AVC_OFF )
|
|
{
|
|
wAVC |= ( AUD_DSP_WR_AVC_AVC_ON_OFF );
|
|
}
|
|
else
|
|
{
|
|
|
|
wAVC |= ( AUD_DSP_WR_AVC_AVC_ON_ON );
|
|
|
|
/* avc decay */
|
|
switch ( volume->avcMode )
|
|
{
|
|
case DRX_AUD_AVC_DECAYTIME_20MS:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
|
|
break;
|
|
case DRX_AUD_AVC_DECAYTIME_8S:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
|
|
break;
|
|
case DRX_AUD_AVC_DECAYTIME_4S:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
|
|
break;
|
|
case DRX_AUD_AVC_DECAYTIME_2S:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
/* max attenuation */
|
|
wAVC &= (u16_t) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
|
|
switch ( volume->avcMaxAtten )
|
|
{
|
|
case DRX_AUD_AVC_MAX_ATTEN_12DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
|
|
break;
|
|
case DRX_AUD_AVC_MAX_ATTEN_18DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
|
|
break;
|
|
case DRX_AUD_AVC_MAX_ATTEN_24DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* max gain */
|
|
wAVC &= (u16_t) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
|
|
switch ( volume->avcMaxGain )
|
|
{
|
|
case DRX_AUD_AVC_MAX_GAIN_0DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
|
|
break;
|
|
case DRX_AUD_AVC_MAX_GAIN_6DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
|
|
break;
|
|
case DRX_AUD_AVC_MAX_GAIN_12DB:
|
|
wAVC |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* avc reference level */
|
|
if ( volume->avcRefLevel > AUD_MAX_AVC_REF_LEVEL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
wAVC &= (u16_t)~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
|
|
wAVC |= (u16_t)( volume->avcRefLevel << AUD_DSP_WR_AVC_AVC_REF_LEV__B );
|
|
|
|
WR16( devAddr, AUD_DSP_WR_AVC__A, wAVC );
|
|
|
|
/* all done, store config in data structure */
|
|
extAttr->audData.volume = *volume;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the I2S settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgI2SOutput_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgOutputI2S ( pDRXDemodInstance_t demod,
|
|
pDRXCfgI2SOutput_t output )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t wI2SConfig = 0;
|
|
u16_t rI2SFreq = 0;
|
|
|
|
if ( output == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
RR16( devAddr, AUD_DEM_RAM_I2S_CONFIG2__A, &wI2SConfig );
|
|
RR16( devAddr, AUD_DSP_WR_I2S_OUT_FS__A, &rI2SFreq );
|
|
|
|
/* I2S mode */
|
|
switch ( wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M )
|
|
{
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
|
|
output->mode = DRX_I2S_MODE_MASTER;
|
|
break;
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
|
|
output->mode = DRX_I2S_MODE_SLAVE;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* I2S format */
|
|
switch ( wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M )
|
|
{
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
|
|
output->format = DRX_I2S_FORMAT_WS_ADVANCED;
|
|
break;
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
|
|
output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* I2S word length */
|
|
switch ( wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M )
|
|
{
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
|
|
output->wordLength = DRX_I2S_WORDLENGTH_16;
|
|
break;
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
|
|
output->wordLength = DRX_I2S_WORDLENGTH_32;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* I2S polarity */
|
|
switch ( wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M )
|
|
{
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
|
|
output->polarity = DRX_I2S_POLARITY_LEFT;
|
|
break;
|
|
case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
|
|
output->polarity = DRX_I2S_POLARITY_RIGHT;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* I2S output enabled */
|
|
if ( ( wI2SConfig & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M )
|
|
== AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE )
|
|
{
|
|
output->outputEnable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
output->outputEnable = FALSE;
|
|
}
|
|
|
|
if ( rI2SFreq > 0 )
|
|
{
|
|
output->frequency = 6144UL * 48000 / rI2SFreq;
|
|
if ( output->wordLength == DRX_I2S_WORDLENGTH_16 )
|
|
{
|
|
output->frequency *= 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
output->frequency = AUD_I2S_FREQUENCY_MAX;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set the I2S settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgI2SOutput_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgOutputI2S ( pDRXDemodInstance_t demod,
|
|
pDRXCfgI2SOutput_t output )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t wI2SConfig = 0;
|
|
u16_t wI2SPadsDataDa = 0;
|
|
u16_t wI2SPadsDataCl = 0;
|
|
u16_t wI2SPadsDataWs = 0;
|
|
u32_t wI2SFreq = 0;
|
|
|
|
if ( output == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
RR16( devAddr, AUD_DEM_RAM_I2S_CONFIG2__A, &wI2SConfig );
|
|
|
|
/* I2S mode */
|
|
wI2SConfig &= (u16_t)~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
|
|
|
|
switch ( output->mode )
|
|
{
|
|
case DRX_I2S_MODE_MASTER:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
|
|
break;
|
|
case DRX_I2S_MODE_SLAVE:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* I2S format */
|
|
wI2SConfig &= (u16_t)~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
|
|
|
|
switch ( output->format )
|
|
{
|
|
case DRX_I2S_FORMAT_WS_ADVANCED:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
|
|
break;
|
|
case DRX_I2S_FORMAT_WS_WITH_DATA:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* I2S word length */
|
|
wI2SConfig &= (u16_t)~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
|
|
|
|
switch ( output->wordLength )
|
|
{
|
|
case DRX_I2S_WORDLENGTH_16:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
|
|
break;
|
|
case DRX_I2S_WORDLENGTH_32:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* I2S polarity */
|
|
wI2SConfig &= (u16_t)~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
|
|
switch ( output->polarity )
|
|
{
|
|
case DRX_I2S_POLARITY_LEFT:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
|
|
break;
|
|
case DRX_I2S_POLARITY_RIGHT:
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* I2S output enabled */
|
|
wI2SConfig &= (u16_t)~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
|
|
if ( output->outputEnable == TRUE )
|
|
{
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
|
|
}
|
|
else
|
|
{
|
|
wI2SConfig |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
|
|
}
|
|
|
|
/*
|
|
I2S frequency
|
|
|
|
wI2SFreq = 6144 * 48000 * nrbits / ( 32 * frequency )
|
|
|
|
16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
|
|
32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
|
|
*/
|
|
if ( ( output->frequency > AUD_I2S_FREQUENCY_MAX ) ||
|
|
output->frequency < AUD_I2S_FREQUENCY_MIN )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
wI2SFreq = (6144UL * 48000UL) + (output->frequency >> 1);
|
|
wI2SFreq /= output->frequency;
|
|
|
|
if ( output->wordLength == DRX_I2S_WORDLENGTH_16 )
|
|
{
|
|
wI2SFreq *= 2;
|
|
}
|
|
|
|
WR16( devAddr, AUD_DEM_WR_I2S_CONFIG2__A, wI2SConfig );
|
|
WR16( devAddr, AUD_DSP_WR_I2S_OUT_FS__A, (u16_t) wI2SFreq );
|
|
|
|
/* configure I2S output pads for master or slave mode */
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY );
|
|
|
|
if (output->mode == DRX_I2S_MODE_MASTER)
|
|
{
|
|
wI2SPadsDataDa = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
|
|
SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
|
|
wI2SPadsDataCl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
|
|
SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
|
|
wI2SPadsDataWs = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
|
|
SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
|
|
}
|
|
else
|
|
{
|
|
wI2SPadsDataDa = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
|
|
SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
|
|
wI2SPadsDataCl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
|
|
SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
|
|
wI2SPadsDataWs = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
|
|
SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
|
|
}
|
|
|
|
WR16( devAddr, SIO_PDR_I2S_DA_CFG__A, wI2SPadsDataDa );
|
|
WR16( devAddr, SIO_PDR_I2S_CL_CFG__A, wI2SPadsDataCl );
|
|
WR16( devAddr, SIO_PDR_I2S_WS_CFG__A, wI2SPadsDataWs );
|
|
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE );
|
|
|
|
|
|
/* all done, store config in data structure */
|
|
extAttr->audData.i2sdata = *output;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the Automatic Standard Select (ASS)
|
|
* and Automatic Sound Change (ASC)
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudAutoSound_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgAutoSound ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudAutoSound_t autoSound )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t rModus = 0;
|
|
|
|
if ( autoSound == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
switch ( rModus & ( AUD_DEM_WR_MODUS_MOD_ASS__M |
|
|
AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M ) )
|
|
{
|
|
case AUD_DEM_WR_MODUS_MOD_ASS_OFF |
|
|
AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
|
|
case AUD_DEM_WR_MODUS_MOD_ASS_OFF |
|
|
AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
|
|
*autoSound = DRX_AUD_AUTO_SOUND_OFF;
|
|
break;
|
|
case AUD_DEM_WR_MODUS_MOD_ASS_ON |
|
|
AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
|
|
*autoSound = DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
|
|
break;
|
|
case AUD_DEM_WR_MODUS_MOD_ASS_ON |
|
|
AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
|
|
*autoSound = DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set the Automatic Standard Select (ASS)
|
|
* and Automatic Sound Change (ASC)
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudAutoSound_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrSetlCfgAutoSound ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudAutoSound_t autoSound )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t rModus = 0;
|
|
u16_t wModus = 0;
|
|
|
|
if ( autoSound == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
wModus = rModus;
|
|
/* clear ASS & ASC bits */
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_ASS__M;
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
|
|
|
|
switch ( *autoSound )
|
|
{
|
|
case DRX_AUD_AUTO_SOUND_OFF:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
|
|
break;
|
|
case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
|
|
break;
|
|
case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
if ( wModus != rModus )
|
|
{
|
|
WR16( devAddr, AUD_DEM_WR_MODUS__A, wModus );
|
|
}
|
|
/* copy to data structure */
|
|
extAttr->audData.autoSound = *autoSound;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the Automatic Standard Select thresholds
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudASSThres_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgASSThres ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudASSThres_t thres )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t thresA2 = 0;
|
|
u16_t thresBtsc = 0;
|
|
u16_t thresNicam = 0;
|
|
|
|
if ( thres == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
RR16( devAddr , AUD_DEM_RAM_A2_THRSHLD__A, &thresA2 );
|
|
RR16( devAddr , AUD_DEM_RAM_BTSC_THRSHLD__A, &thresBtsc );
|
|
RR16( devAddr , AUD_DEM_RAM_NICAM_THRSHLD__A, &thresNicam );
|
|
|
|
thres->a2 = thresA2;
|
|
thres->btsc = thresBtsc;
|
|
thres->nicam = thresNicam;
|
|
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the Automatic Standard Select thresholds
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudASSThres_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgASSThres ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudASSThres_t thres )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
if ( thres == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
WR16( devAddr , AUD_DEM_WR_A2_THRSHLD__A, thres->a2 );
|
|
WR16( devAddr , AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc );
|
|
WR16( devAddr , AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam );
|
|
|
|
/* update DRXK data structure with hardware values */
|
|
extAttr->audData.assThresholds = *thres;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get Audio Carrier settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudCarrier_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgCarrier ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudCarriers_t carriers )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wModus = 0;
|
|
|
|
u16_t dcoAHi = 0;
|
|
u16_t dcoALo = 0;
|
|
u16_t dcoBHi = 0;
|
|
u16_t dcoBLo = 0;
|
|
|
|
u32_t valA = 0;
|
|
u32_t valB = 0;
|
|
|
|
u16_t dcLvlA = 0;
|
|
u16_t dcLvlB = 0;
|
|
|
|
u16_t cmThesA = 0;
|
|
u16_t cmThesB = 0;
|
|
|
|
if ( carriers == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &wModus ));
|
|
|
|
/* Behaviour of primary audio channel */
|
|
switch ( wModus & ( AUD_DEM_WR_MODUS_MOD_CM_A__M) )
|
|
{
|
|
case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
|
|
carriers->a.opt = DRX_NO_CARRIER_MUTE;
|
|
break;
|
|
case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
|
|
carriers->a.opt = DRX_NO_CARRIER_NOISE;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
/* Behaviour of secondary audio channel */
|
|
switch ( wModus & ( AUD_DEM_WR_MODUS_MOD_CM_B__M) )
|
|
{
|
|
case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
|
|
carriers->b.opt = DRX_NO_CARRIER_MUTE;
|
|
break;
|
|
case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
|
|
carriers->b.opt = DRX_NO_CARRIER_NOISE;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
/* frequency adjustment for primary & secondary audio channel */
|
|
RR16( devAddr, AUD_DEM_RAM_DCO_A_HI__A, &dcoAHi );
|
|
RR16( devAddr, AUD_DEM_RAM_DCO_A_LO__A, &dcoALo );
|
|
RR16( devAddr, AUD_DEM_RAM_DCO_B_HI__A, &dcoBHi );
|
|
RR16( devAddr, AUD_DEM_RAM_DCO_B_LO__A, &dcoBLo );
|
|
|
|
valA = ( ( (u32_t) dcoAHi) << 12 ) | ( (u32_t) dcoALo & 0xFFF );
|
|
valB = ( ( (u32_t) dcoBHi) << 12 ) | ( (u32_t) dcoBLo & 0xFFF );
|
|
|
|
/* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
|
|
carriers->a.dco = DRX_S24TODRXFREQ( valA ) * 2L / 1657L;
|
|
carriers->b.dco = DRX_S24TODRXFREQ( valB ) * 2L / 1657L;
|
|
|
|
/* DC level of the incoming FM signal on the primary
|
|
& seconday sound channel */
|
|
RR16( devAddr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dcLvlA );
|
|
RR16( devAddr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dcLvlB );
|
|
|
|
/* offset (kHz) = (dcLvl / 322) */
|
|
carriers->a.shift = ( DRX_U16TODRXFREQ( dcLvlA ) / 322L );
|
|
carriers->b.shift = ( DRX_U16TODRXFREQ( dcLvlB ) / 322L );
|
|
|
|
/* Carrier detetcion threshold for primary & secondary channel */
|
|
RR16( devAddr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cmThesA);
|
|
RR16( devAddr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cmThesB);
|
|
|
|
carriers->a.thres = cmThesA;
|
|
carriers->b.thres = cmThesB;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set Audio Carrier settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudCarrier_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgCarrier ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudCarriers_t carriers )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wModus = 0;
|
|
u16_t rModus = 0;
|
|
|
|
u16_t dcoAHi = 0;
|
|
u16_t dcoALo = 0;
|
|
u16_t dcoBHi = 0;
|
|
u16_t dcoBLo = 0;
|
|
|
|
s32_t valA = 0;
|
|
s32_t valB = 0;
|
|
|
|
if ( carriers == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
|
|
wModus = rModus;
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_CM_A__M;
|
|
/* Behaviour of primary audio channel */
|
|
switch ( carriers->a.opt )
|
|
{
|
|
case DRX_NO_CARRIER_MUTE:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
|
|
break;
|
|
case DRX_NO_CARRIER_NOISE:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
/* Behaviour of secondary audio channel */
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_CM_B__M;
|
|
switch ( carriers->b.opt )
|
|
{
|
|
case DRX_NO_CARRIER_MUTE:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
|
|
break;
|
|
case DRX_NO_CARRIER_NOISE:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
/* now update the modus register */
|
|
if ( wModus != rModus)
|
|
{
|
|
WR16( devAddr, AUD_DEM_WR_MODUS__A, wModus );
|
|
}
|
|
|
|
/* frequency adjustment for primary & secondary audio channel */
|
|
valA = (s32_t) ( ( carriers->a.dco ) * 1657L / 2);
|
|
valB = (s32_t) ( ( carriers->b.dco ) * 1657L / 2);
|
|
|
|
dcoAHi = (u16_t) ( ( valA >> 12 ) & 0xFFF );
|
|
dcoALo = (u16_t) ( valA & 0xFFF );
|
|
dcoBHi = (u16_t) ( ( valB >> 12 ) & 0xFFF );
|
|
dcoBLo = (u16_t) ( valB & 0xFFF );
|
|
|
|
WR16( devAddr, AUD_DEM_WR_DCO_A_HI__A, dcoAHi );
|
|
WR16( devAddr, AUD_DEM_WR_DCO_A_LO__A, dcoALo );
|
|
WR16( devAddr, AUD_DEM_WR_DCO_B_HI__A, dcoBHi );
|
|
WR16( devAddr, AUD_DEM_WR_DCO_B_LO__A, dcoBLo );
|
|
|
|
/* Carrier detetcion threshold for primary & secondary channel */
|
|
WR16( devAddr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres);
|
|
WR16( devAddr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres);
|
|
|
|
/* update DRXK data structure */
|
|
extAttr->audData.carriers = *carriers;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get I2S Source, I2S matrix and FM matrix
|
|
* \param demod instance of demodulator
|
|
* \param pointer to pDRXAudmixer_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgMixer ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudMixer_t mixer )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t srcI2SMatr = 0;
|
|
u16_t fmMatr = 0;
|
|
|
|
if ( mixer == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* Source Selctor */
|
|
RR16( devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, &srcI2SMatr);
|
|
|
|
switch ( srcI2SMatr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M )
|
|
{
|
|
case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
|
|
mixer->sourceI2S = DRX_AUD_SRC_MONO;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
|
|
mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_AB;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
|
|
mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_A;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
|
|
mixer->sourceI2S = DRX_AUD_SRC_STEREO_OR_B;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* Matrix */
|
|
switch ( srcI2SMatr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M )
|
|
{
|
|
case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
|
|
mixer->matrixI2S = DRX_AUD_I2S_MATRIX_MONO;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
|
|
mixer->matrixI2S = DRX_AUD_I2S_MATRIX_STEREO;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
|
|
mixer->matrixI2S = DRX_AUD_I2S_MATRIX_A_MONO;
|
|
break;
|
|
case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
|
|
mixer->matrixI2S = DRX_AUD_I2S_MATRIX_B_MONO;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/* FM Matrix */
|
|
RR16( devAddr, AUD_DEM_WR_FM_MATRIX__A, &fmMatr );
|
|
switch ( fmMatr & AUD_DEM_WR_FM_MATRIX__M )
|
|
{
|
|
case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
|
|
mixer->matrixFm = DRX_AUD_FM_MATRIX_NO_MATRIX;
|
|
break;
|
|
case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
|
|
mixer->matrixFm = DRX_AUD_FM_MATRIX_GERMAN;
|
|
break;
|
|
case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
|
|
mixer->matrixFm = DRX_AUD_FM_MATRIX_KOREAN;
|
|
break;
|
|
case AUD_DEM_WR_FM_MATRIX_SOUND_A:
|
|
mixer->matrixFm = DRX_AUD_FM_MATRIX_SOUND_A;
|
|
break;
|
|
case AUD_DEM_WR_FM_MATRIX_SOUND_B:
|
|
mixer->matrixFm = DRX_AUD_FM_MATRIX_SOUND_B;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set I2S Source, I2S matrix and FM matrix
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXAudmixer_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgMixer ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudMixer_t mixer )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t srcI2SMatr = 0;
|
|
u16_t fmMatr = 0;
|
|
|
|
if ( mixer == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* Source Selctor */
|
|
RR16( devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, &srcI2SMatr);
|
|
srcI2SMatr &= (u16_t)~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
|
|
|
|
switch (mixer->sourceI2S)
|
|
{
|
|
case DRX_AUD_SRC_MONO:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
|
|
break;
|
|
case DRX_AUD_SRC_STEREO_OR_AB:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
|
|
break;
|
|
case DRX_AUD_SRC_STEREO_OR_A:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
|
|
break;
|
|
case DRX_AUD_SRC_STEREO_OR_B:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* Matrix */
|
|
srcI2SMatr &= (u16_t)~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
|
|
switch (mixer->matrixI2S)
|
|
{
|
|
case DRX_AUD_I2S_MATRIX_MONO:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
|
|
break;
|
|
case DRX_AUD_I2S_MATRIX_STEREO:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO ;
|
|
break;
|
|
case DRX_AUD_I2S_MATRIX_A_MONO:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
|
|
break;
|
|
case DRX_AUD_I2S_MATRIX_B_MONO:
|
|
srcI2SMatr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
/* write the result */
|
|
WR16( devAddr, AUD_DSP_WR_SRC_I2S_MATR__A, srcI2SMatr);
|
|
|
|
/* FM Matrix */
|
|
RR16( devAddr, AUD_DEM_WR_FM_MATRIX__A, &fmMatr );
|
|
fmMatr &= (u16_t)~AUD_DEM_WR_FM_MATRIX__M;
|
|
switch (mixer->matrixFm)
|
|
{
|
|
case DRX_AUD_FM_MATRIX_NO_MATRIX:
|
|
fmMatr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
|
|
break;
|
|
case DRX_AUD_FM_MATRIX_GERMAN:
|
|
fmMatr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
|
|
break;
|
|
case DRX_AUD_FM_MATRIX_KOREAN:
|
|
fmMatr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
|
|
break;
|
|
case DRX_AUD_FM_MATRIX_SOUND_A:
|
|
fmMatr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
|
|
break;
|
|
case DRX_AUD_FM_MATRIX_SOUND_B:
|
|
fmMatr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* Only write if ASS is off */
|
|
if ( extAttr->audData.autoSound == DRX_AUD_AUTO_SOUND_OFF )
|
|
{
|
|
WR16( devAddr, AUD_DEM_WR_FM_MATRIX__A, fmMatr );
|
|
}
|
|
|
|
/* update the data structure with hardware state */
|
|
extAttr->audData.mixer = *mixer;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set AV Sync settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXICfgAVSync_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgAVSync ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudAVSync_t avSync )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wAudVidSync = 0;
|
|
|
|
if ( avSync == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* audio/video synchronisation */
|
|
RR16( devAddr, AUD_DSP_WR_AV_SYNC__A, &wAudVidSync );
|
|
|
|
wAudVidSync &= (u16_t)~AUD_DSP_WR_AV_SYNC_AV_ON__M;
|
|
|
|
if ( *avSync == DRX_AUD_AVSYNC_OFF )
|
|
{
|
|
wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
|
|
}
|
|
else
|
|
{
|
|
wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
|
|
}
|
|
|
|
wAudVidSync &= (u16_t)~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
|
|
|
|
switch ( *avSync )
|
|
{
|
|
case DRX_AUD_AVSYNC_NTSC:
|
|
wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
|
|
break;
|
|
case DRX_AUD_AVSYNC_MONOCHROME:
|
|
wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
|
|
break;
|
|
case DRX_AUD_AVSYNC_PAL_SECAM:
|
|
wAudVidSync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
|
|
break;
|
|
case DRX_AUD_AVSYNC_OFF:
|
|
/* OK */
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
WR16( devAddr, AUD_DSP_WR_AV_SYNC__A, wAudVidSync );
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get AV Sync settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXICfgAVSync_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgAVSync ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudAVSync_t avSync )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wAudVidSync = 0;
|
|
|
|
if ( avSync == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* audio/video synchronisation */
|
|
RR16( devAddr, AUD_DSP_WR_AV_SYNC__A, &wAudVidSync );
|
|
|
|
if ( ( wAudVidSync & AUD_DSP_WR_AV_SYNC_AV_ON__M ) ==
|
|
AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE )
|
|
{
|
|
*avSync = DRX_AUD_AVSYNC_OFF;
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
switch ( wAudVidSync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M )
|
|
{
|
|
case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
|
|
*avSync = DRX_AUD_AVSYNC_NTSC;
|
|
break;
|
|
case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
|
|
*avSync = DRX_AUD_AVSYNC_MONOCHROME;
|
|
break;
|
|
case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
|
|
*avSync = DRX_AUD_AVSYNC_PAL_SECAM;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get deviation mode
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudDeviation_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgDev ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudDeviation_t dev )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t rModus = 0;
|
|
|
|
|
|
if ( dev == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod->myI2CDevAddr;
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
switch ( rModus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M)
|
|
{
|
|
case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
|
|
*dev = DRX_AUD_DEVIATION_NORMAL;
|
|
break;
|
|
case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
|
|
*dev = DRX_AUD_DEVIATION_HIGH;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get deviation mode
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudDeviation_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgDev ( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudDeviation_t dev )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wModus = 0;
|
|
u16_t rModus = 0;
|
|
|
|
if ( dev == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod->myI2CDevAddr;
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
wModus = rModus;
|
|
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
|
|
|
|
switch ( *dev )
|
|
{
|
|
case DRX_AUD_DEVIATION_NORMAL:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
|
|
break;
|
|
case DRX_AUD_DEVIATION_HIGH:
|
|
wModus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
|
|
break;
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* now update the modus register */
|
|
if ( wModus != rModus)
|
|
{
|
|
WR16( devAddr, AUD_DEM_WR_MODUS__A, wModus );
|
|
}
|
|
/* store in drxk data struct */
|
|
extAttr->audData.deviation = *dev;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get Prescaler settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudPrescale_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetCfgPrescale( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudPrescale_t presc )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t rMaxFMDeviation = 0;
|
|
u16_t rNicamPrescaler = 0;
|
|
|
|
if ( presc == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* read register data */
|
|
RR16( devAddr, AUD_DSP_WR_NICAM_PRESC__A, &rNicamPrescaler );
|
|
RR16( devAddr, AUD_DSP_WR_FM_PRESC__A, &rMaxFMDeviation );
|
|
|
|
/* calculate max FM deviation */
|
|
rMaxFMDeviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
|
|
if ( rMaxFMDeviation > 0 )
|
|
{
|
|
presc->fmDeviation = 3600UL + (rMaxFMDeviation >> 1);
|
|
presc->fmDeviation /= rMaxFMDeviation;
|
|
}
|
|
else
|
|
{
|
|
presc->fmDeviation = 380; /* kHz */
|
|
}
|
|
|
|
/* calculate NICAM gain from pre-scaler */
|
|
/*
|
|
nicamGain = 20 * ( log10( preScaler / 16) )
|
|
= ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
|
|
|
|
because Log10Times100() cannot return negative numbers
|
|
= ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
|
|
|
|
|
|
for 0.1dB resolution:
|
|
|
|
nicamGain = 200 * ( log10( preScaler / 16) )
|
|
= 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
|
|
= ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
|
|
|
|
|
|
*/
|
|
rNicamPrescaler >>= 8;
|
|
if ( rNicamPrescaler <= 1 )
|
|
{
|
|
presc->nicamGain = -241;
|
|
}
|
|
else
|
|
{
|
|
|
|
presc->nicamGain = (s16_t)( ( (s32_t)
|
|
( Log10Times100( 10 * rNicamPrescaler *
|
|
rNicamPrescaler ) ) -
|
|
(s32_t)
|
|
( Log10Times100( 10 * 16 * 16 ) ) ) );
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set Prescaler settings
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXCfgAudPrescale_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetCfgPrescale( pDRXDemodInstance_t demod,
|
|
pDRXCfgAudPrescale_t presc )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t wMaxFMDeviation = 0;
|
|
u16_t nicamPrescaler;
|
|
|
|
if ( presc == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
/* setting of max FM deviation */
|
|
wMaxFMDeviation = (u16_t)(Frac (3600UL, presc->fmDeviation, 0));
|
|
wMaxFMDeviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
|
|
if ( wMaxFMDeviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION )
|
|
{
|
|
wMaxFMDeviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
|
|
}
|
|
|
|
/* NICAM Prescaler */
|
|
if( ( presc->nicamGain >= -241) && ( presc->nicamGain <= 180) )
|
|
{
|
|
/* calculation
|
|
|
|
prescaler = 16 * 10^( GdB / 20 )
|
|
|
|
minval of GdB = -20*log( 16 ) = -24.1dB
|
|
|
|
negative numbers not allowed for dB2LinTimes100, so
|
|
|
|
prescaler = 16 * 10^( GdB / 20 )
|
|
= 10^( (GdB / 20) + log10(16) )
|
|
= 10^( (GdB + 20log10(16)) / 20 )
|
|
|
|
in 0.1dB
|
|
|
|
= 10^( G0.1dB + 200log10(16)) / 200 )
|
|
|
|
*/
|
|
nicamPrescaler = (u16_t)
|
|
( ( dB2LinTimes100( presc->nicamGain + 241UL ) + 50UL ) / 100UL );
|
|
|
|
/* clip result */
|
|
if ( nicamPrescaler > 127 )
|
|
{
|
|
nicamPrescaler = 127;
|
|
}
|
|
|
|
/* shift before writing to register */
|
|
nicamPrescaler <<= 8;
|
|
}
|
|
else
|
|
{
|
|
return(DRX_STS_INVALID_ARG);
|
|
}
|
|
/* end of setting NICAM Prescaler */
|
|
|
|
WR16( devAddr, AUD_DSP_WR_NICAM_PRESC__A, nicamPrescaler );
|
|
WR16( devAddr, AUD_DSP_WR_FM_PRESC__A, wMaxFMDeviation );
|
|
|
|
extAttr->audData.prescale = *presc;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Beep
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXAudBeep_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlBeep ( pDRXDemodInstance_t demod,
|
|
pDRXAudBeep_t beep )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
|
|
u16_t theBeep = 0;
|
|
u16_t volume = 0;
|
|
u32_t frequency = 0;
|
|
|
|
|
|
if ( beep == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
if (( beep->volume > 0 ) || ( beep->volume < -127 ))
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
if ( beep->frequency > 3000 )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
volume = (u16_t)beep->volume + 127;
|
|
theBeep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
|
|
|
|
|
|
frequency = ( (u32_t) beep->frequency ) * 23 / 500 ;
|
|
if ( frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M )
|
|
{
|
|
frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
|
|
}
|
|
theBeep |= (u16_t) frequency;
|
|
|
|
if ( beep->mute == TRUE )
|
|
{
|
|
theBeep = 0;
|
|
}
|
|
|
|
WR16( devAddr, AUD_DSP_WR_BEEPER__A, theBeep);
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Set an audio standard
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXAudStandard_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlSetStandard ( pDRXDemodInstance_t demod,
|
|
pDRXAudStandard_t standard )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t currentStandard = DRX_STANDARD_UNKNOWN;
|
|
|
|
u16_t wStandard = 0;
|
|
u16_t wModus = 0;
|
|
u16_t rModus = 0;
|
|
|
|
Bool_t muteBuffer = FALSE;
|
|
s16_t volumeBuffer = 0;
|
|
u16_t wVolume = 0;
|
|
|
|
if ( standard == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , FALSE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
|
|
/* reset RDS data availability flag */
|
|
extAttr->audData.rdsDataPresent = FALSE;
|
|
|
|
|
|
/* we need to mute from here to avoid noise during standard switching */
|
|
muteBuffer = extAttr->audData.volume.mute;
|
|
volumeBuffer = extAttr->audData.volume.volume;
|
|
|
|
extAttr->audData.volume.mute = TRUE;
|
|
/* restore data structure from DRX ExtAttr, call volume first to mute */
|
|
CHK_ERROR ( AUDCtrlSetCfgVolume
|
|
( demod, &extAttr->audData.volume ) );
|
|
CHK_ERROR ( AUDCtrlSetCfgCarrier
|
|
( demod, &extAttr->audData.carriers ) );
|
|
CHK_ERROR ( AUDCtrlSetCfgASSThres
|
|
( demod, &extAttr->audData.assThresholds ) );
|
|
CHK_ERROR ( AUDCtrSetlCfgAutoSound
|
|
( demod, &extAttr->audData.autoSound ) );
|
|
CHK_ERROR ( AUDCtrlSetCfgMixer
|
|
( demod, &extAttr->audData.mixer ) );
|
|
CHK_ERROR ( AUDCtrlSetCfgAVSync
|
|
( demod, &extAttr->audData.avSync ) );
|
|
CHK_ERROR ( AUDCtrlSetCfgOutputI2S
|
|
( demod, &extAttr->audData.i2sdata ) );
|
|
|
|
/* get prescaler from presets */
|
|
CHK_ERROR ( AUDCtrlSetCfgPrescale
|
|
( demod, &extAttr->audData.prescale) );
|
|
|
|
CHK_ERROR ( AUDGetModus ( demod, &rModus ));
|
|
|
|
wModus = rModus;
|
|
|
|
switch ( *standard )
|
|
{
|
|
case DRX_AUD_STANDARD_AUTO:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
|
|
break;
|
|
case DRX_AUD_STANDARD_BTSC:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
|
|
if (extAttr->audData.btscDetect == DRX_BTSC_MONO_AND_SAP)
|
|
{
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
|
|
}
|
|
break;
|
|
case DRX_AUD_STANDARD_A2:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
|
|
break;
|
|
case DRX_AUD_STANDARD_EIAJ:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
|
|
break;
|
|
case DRX_AUD_STANDARD_FM_STEREO:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
|
|
break;
|
|
case DRX_AUD_STANDARD_BG_FM:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
|
|
break;
|
|
case DRX_AUD_STANDARD_D_K1:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
|
|
break;
|
|
case DRX_AUD_STANDARD_D_K2:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
|
|
break;
|
|
case DRX_AUD_STANDARD_D_K3:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
|
|
break;
|
|
case DRX_AUD_STANDARD_BG_NICAM_FM:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
|
|
break;
|
|
case DRX_AUD_STANDARD_L_NICAM_AM:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
|
|
break;
|
|
case DRX_AUD_STANDARD_I_NICAM_FM:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
|
|
break;
|
|
case DRX_AUD_STANDARD_D_K_NICAM_FM:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
|
|
break;
|
|
case DRX_AUD_STANDARD_UNKNOWN:
|
|
wStandard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
|
|
break;
|
|
default:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
if ( *standard == DRX_AUD_STANDARD_AUTO )
|
|
{
|
|
/* we need the current standard here */
|
|
currentStandard = extAttr->standard;
|
|
|
|
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
|
|
|
|
if ( ( currentStandard == DRX_STANDARD_PAL_SECAM_L ) ||
|
|
( currentStandard == DRX_STANDARD_PAL_SECAM_LP ) )
|
|
{
|
|
wModus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
|
|
}
|
|
else
|
|
{
|
|
wModus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
|
|
}
|
|
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
|
|
if ( currentStandard == DRX_STANDARD_NTSC )
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
|
|
|
|
}
|
|
else /* non USA, ignore standard M to save time */
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
|
|
|
|
/* just get hardcoded deemphasis and activate here */
|
|
if ( extAttr->audData.deemph == DRX_AUD_FM_DEEMPH_50US )
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
|
|
}
|
|
else
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
|
|
}
|
|
|
|
wModus &= (u16_t)~AUD_DEM_WR_MODUS_MOD_BTSC__M;
|
|
if( extAttr->audData.btscDetect == DRX_BTSC_STEREO )
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
|
|
}
|
|
else /* DRX_BTSC_MONO_AND_SAP */
|
|
{
|
|
wModus |= ( AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
|
|
}
|
|
|
|
if ( wModus != rModus)
|
|
{
|
|
WR16( devAddr, AUD_DEM_WR_MODUS__A, wModus );
|
|
}
|
|
|
|
WR16( devAddr, AUD_DEM_WR_STANDARD_SEL__A, wStandard );
|
|
|
|
/**************************************************************************/
|
|
/* NOT calling AUDCtrlSetCfgVolume to avoid interfering standard */
|
|
/* detection, need to keep things very minimal here, but keep audio */
|
|
/* buffers intact */
|
|
/**************************************************************************/
|
|
extAttr->audData.volume.mute = muteBuffer;
|
|
if ( extAttr->audData.volume.mute == FALSE )
|
|
{
|
|
wVolume |= (u16_t) ( ( volumeBuffer + AUD_VOLUME_ZERO_DB ) <<
|
|
AUD_DSP_WR_VOLUME_VOL_MAIN__B );
|
|
WR16( devAddr, AUD_DSP_WR_VOLUME__A, wVolume );
|
|
}
|
|
|
|
/* write standard selected */
|
|
extAttr->audData.audioStandard = *standard;
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Get the current audio standard
|
|
* \param demod instance of demodulator
|
|
* \param pointer to DRXAudStandard_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
AUDCtrlGetStandard ( pDRXDemodInstance_t demod,
|
|
pDRXAudStandard_t standard )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
u16_t rData = 0;
|
|
|
|
if ( standard == NULL )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = (pI2CDeviceAddr_t)demod->myI2CDevAddr;
|
|
|
|
/* power up */
|
|
if ( extAttr->audData.audioIsActive == FALSE )
|
|
{
|
|
CHK_ERROR ( PowerUpAud( demod , TRUE ) );
|
|
extAttr->audData.audioIsActive = TRUE;
|
|
}
|
|
|
|
*standard = DRX_AUD_STANDARD_UNKNOWN;
|
|
|
|
RR16( devAddr, AUD_DEM_RD_STANDARD_RES__A, &rData );
|
|
|
|
/* return OK if the detection is not ready yet */
|
|
if ( rData >=
|
|
AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE )
|
|
{
|
|
*standard = DRX_AUD_STANDARD_NOT_READY;
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/* detection done, return correct standard */
|
|
switch ( rData )
|
|
{
|
|
/* no standard detected */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
|
|
*standard = DRX_AUD_STANDARD_UNKNOWN;
|
|
break;
|
|
/* standard is KOREA(A2) */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
|
|
*standard = DRX_AUD_STANDARD_A2;
|
|
break;
|
|
/* standard is EIA-J (Japan) */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
|
|
*standard = DRX_AUD_STANDARD_EIAJ;
|
|
break;
|
|
/* standard is BTSC-stereo */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
|
|
*standard = DRX_AUD_STANDARD_BTSC;
|
|
break;
|
|
/* standard is BTSC-mono (SAP) */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
|
|
*standard = DRX_AUD_STANDARD_BTSC;
|
|
break;
|
|
/* standard is FM radio */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
|
|
*standard = DRX_AUD_STANDARD_FM_STEREO;
|
|
break;
|
|
/* standard is BG FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
|
|
*standard = DRX_AUD_STANDARD_BG_FM;
|
|
break;
|
|
/* standard is DK-1 FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
|
|
*standard = DRX_AUD_STANDARD_D_K1;
|
|
break;
|
|
/* standard is DK-2 FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
|
|
*standard = DRX_AUD_STANDARD_D_K2;
|
|
break;
|
|
/* standard is DK-3 FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
|
|
*standard = DRX_AUD_STANDARD_D_K3;
|
|
break;
|
|
/* standard is BG-NICAM FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
|
|
*standard = DRX_AUD_STANDARD_BG_NICAM_FM;
|
|
break;
|
|
/* standard is L-NICAM AM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
|
|
*standard = DRX_AUD_STANDARD_L_NICAM_AM;
|
|
break;
|
|
/* standard is I-NICAM FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
|
|
*standard = DRX_AUD_STANDARD_I_NICAM_FM;
|
|
break;
|
|
/* standard is DK-NICAM FM */
|
|
case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
|
|
*standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
|
|
break;
|
|
default:
|
|
*standard = DRX_AUD_STANDARD_UNKNOWN;
|
|
}
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return DRX_STS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief Retreive lock status in case of FM standard
|
|
* \param demod instance of demodulator
|
|
* \param pointer to lock status
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
FmLockStatus( pDRXDemodInstance_t demod,
|
|
pDRXLockStatus_t lockStat )
|
|
{
|
|
DRXAudStatus_t status;
|
|
|
|
/* Check detection of audio carriers */
|
|
CHK_ERROR( AUDCtrlGetCarrierDetectStatus ( demod, &status ) );
|
|
|
|
/* locked if either primary or secondary carrier is detected */
|
|
if ( ( status.carrierA == TRUE ) ||
|
|
( status.carrierB == TRUE ) )
|
|
{
|
|
*lockStat = DRX_LOCKED;
|
|
} else {
|
|
*lockStat = DRX_NOT_LOCKED;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \brief retreive signal quality in case of FM standard
|
|
* \param demod instance of demodulator
|
|
* \param pointer to signal quality
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Only the quality indicator field is will be supplied.
|
|
* This will either be 0% or 100%, nothing in between.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
FmSigQuality( pDRXDemodInstance_t demod,
|
|
pDRXSigQuality_t sigQuality )
|
|
{
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
|
|
CHK_ERROR( FmLockStatus( demod, &lockStatus ) );
|
|
if ( lockStatus == DRX_LOCKED )
|
|
{
|
|
sigQuality->indicator = 100;
|
|
} else {
|
|
sigQuality->indicator = 0;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*===========================================================================*/
|
|
/*== END AUDIO DATAPATH FUNCTIONS ==*/
|
|
/*===========================================================================*/
|
|
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
/*== OOB DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
/*============================================================================*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
/**
|
|
* \fn DRXStatus_t GetOOBLockStatus ()
|
|
* \brief Get OOB lock status.
|
|
* \param devAddr I2C address
|
|
\ oobLock OOB lock status.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Gets OOB lock status
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetOOBLockStatus( pDRXDemodInstance_t demod,
|
|
pI2CDeviceAddr_t devAddr,
|
|
pDRXLockStatus_t oobLock )
|
|
{
|
|
DRXJSCUCmd_t scuCmd;
|
|
u16_t cmdResult[2];
|
|
u16_t OOBLockState;
|
|
|
|
*oobLock = DRX_NOT_LOCKED;
|
|
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
|
|
scuCmd.resultLen = 2;
|
|
scuCmd.result = cmdResult;
|
|
scuCmd.parameterLen = 0;
|
|
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
|
|
if ( scuCmd.result[1] < 0x4000 )
|
|
{
|
|
/* 0x00 NOT LOCKED */
|
|
*oobLock = DRX_NOT_LOCKED;
|
|
}
|
|
else if ( scuCmd.result[1] < 0x8000 )
|
|
{
|
|
/* 0x40 DEMOD LOCKED */
|
|
*oobLock = DRXJ_OOB_SYNC_LOCK;
|
|
}
|
|
else if ( scuCmd.result[1] < 0xC000 )
|
|
{
|
|
/* 0x80 DEMOD + OOB LOCKED (system lock) */
|
|
OOBLockState = scuCmd.result[1] & 0x00FF;
|
|
|
|
if(OOBLockState & 0x0008)
|
|
{
|
|
*oobLock = DRXJ_OOB_SYNC_LOCK;
|
|
}
|
|
else if ((OOBLockState & 0x0002) && (OOBLockState & 0x0001))
|
|
{
|
|
*oobLock = DRXJ_OOB_AGC_LOCK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
|
|
*oobLock = DRX_NEVER_LOCK;
|
|
}
|
|
|
|
/* *oobLock = scuCmd.result[1]; */
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetOOBSymbolRateOffset ()
|
|
* \brief Get OOB Symbol rate offset. Unit is [ppm]
|
|
* \param devAddr I2C address
|
|
* \ Symbol Rate Offset OOB parameter.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Gets OOB frequency offset
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetOOBSymbolRateOffset( pI2CDeviceAddr_t devAddr, ps32_t SymbolRateOffset )
|
|
{
|
|
/* offset = -{(timingOffset/2^19)*(symbolRate/12,656250MHz)}*10^6 [ppm] */
|
|
/* offset = -{(timingOffset/2^19)*(symbolRate/12656250)}*10^6 [ppm] */
|
|
/* after reconfiguration: */
|
|
/* offset = -{(timingOffset*symbolRate)/(2^19*12656250)}*10^6 [ppm] */
|
|
/* shift symbol rate left by 5 without lossing information */
|
|
/* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
|
|
/* shift 10^6 left by 6 without loosing information */
|
|
/* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
|
|
/* trim 12656250/15625 = 810 */
|
|
/* offset = -{(timingOffset*(symbolRate * 2^-5))/(2^8*810)} [ppm] */
|
|
/* offset = -[(symbolRate * 2^-5)*(timingOffset)/(2^8)]/810 [ppm] */
|
|
s32_t timingOffset = 0;
|
|
u32_t unsignedTimingOffset = 0;
|
|
s32_t divisionFactor = 810;
|
|
u16_t data = 0;
|
|
u32_t symbolRate = 0;
|
|
Bool_t negative = FALSE;
|
|
|
|
*SymbolRateOffset = 0;
|
|
/* read data rate */
|
|
SARR16( devAddr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data );
|
|
switch(data & SCU_RAM_ORX_RF_RX_DATA_RATE__M)
|
|
{
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
|
|
symbolRate = 1024000;/* bps */
|
|
break;
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
|
|
symbolRate = 772000;/* bps */
|
|
break;
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
|
|
symbolRate = 1544000;/* bps */
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
RR16( devAddr, ORX_CON_CTI_DTI_R__A, &data );
|
|
/* convert data to positive and keep information about sign */
|
|
if((data & 0x8000) == 0x8000){
|
|
if(data == 0x8000)
|
|
unsignedTimingOffset = 32768;
|
|
else
|
|
unsignedTimingOffset = 0x00007FFF & (u32_t)(-data);
|
|
negative = TRUE;
|
|
}
|
|
else
|
|
unsignedTimingOffset = (u32_t)data;
|
|
|
|
symbolRate = symbolRate >> 5;
|
|
unsignedTimingOffset = ( unsignedTimingOffset * symbolRate );
|
|
unsignedTimingOffset = Frac( unsignedTimingOffset, 256, FRAC_ROUND );
|
|
unsignedTimingOffset = Frac( unsignedTimingOffset,
|
|
divisionFactor, FRAC_ROUND );
|
|
if(negative)
|
|
timingOffset = (s32_t)unsignedTimingOffset;
|
|
else
|
|
timingOffset = -(s32_t)unsignedTimingOffset;
|
|
|
|
*SymbolRateOffset = timingOffset;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t GetOOBFreqOffset ()
|
|
* \brief Get OOB lock status.
|
|
* \param devAddr I2C address
|
|
* \ freqOffset OOB frequency offset.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Gets OOB frequency offset
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetOOBFreqOffset( pDRXDemodInstance_t demod, pDRXFrequency_t freqOffset )
|
|
{
|
|
u16_t data = 0;
|
|
u16_t rot = 0;
|
|
u16_t symbolRateReg = 0;
|
|
u32_t symbolRate = 0;
|
|
s32_t coarseFreqOffset = 0;
|
|
s32_t fineFreqOffset = 0;
|
|
s32_t fineSign = 1;
|
|
s32_t coarseSign = 1;
|
|
u32_t data64Hi = 0;
|
|
u32_t data64Lo = 0;
|
|
u32_t tempFreqOffset = 0;
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
/* check arguments */
|
|
if ( ( demod == NULL ) ||
|
|
( freqOffset == NULL ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
*freqOffset = 0;
|
|
|
|
/* read sign (spectrum inversion) */
|
|
RR16( devAddr, ORX_FWP_IQM_FRQ_W__A, &rot );
|
|
|
|
/* read frequency offset */
|
|
SARR16( devAddr, SCU_RAM_ORX_FRQ_OFFSET__A, &data );
|
|
/* find COARSE frequency offset */
|
|
/* coarseFreqOffset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
|
|
if (data & 0x8000)
|
|
{
|
|
data = (0xffff - data + 1);
|
|
coarseSign = -1;
|
|
}
|
|
Mult32 ( data, (commonAttr->sysClockFreq * 1000)/6, &data64Hi, &data64Lo );
|
|
tempFreqOffset = (((data64Lo >> 21) & 0x7ff) | (data64Hi << 11));
|
|
|
|
/* get value in KHz */
|
|
coarseFreqOffset = coarseSign * Frac( tempFreqOffset, 1000, FRAC_ROUND ); /* KHz */
|
|
/* read data rate */
|
|
SARR16( devAddr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbolRateReg );
|
|
switch(symbolRateReg & SCU_RAM_ORX_RF_RX_DATA_RATE__M)
|
|
{
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
|
|
symbolRate = 1024000;
|
|
break;
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
|
|
symbolRate = 772000;
|
|
break;
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
|
|
case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
|
|
symbolRate = 1544000;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* find FINE frequency offset */
|
|
/* fineFreqOffset = ( (CORRECTION_VALUE*symbolRate) >> 18 ); */
|
|
RR16( devAddr, ORX_CON_CPH_FRQ_R__A, &data );
|
|
/* at least 5 MSB are 0 so first divide with 2^5 without information loss*/
|
|
fineFreqOffset = ( symbolRate >> 5 );
|
|
if (data & 0x8000)
|
|
{
|
|
fineFreqOffset *= 0xffff - data + 1; /* Hz */
|
|
fineSign = -1;
|
|
} else {
|
|
fineFreqOffset *= data; /* Hz */
|
|
}
|
|
/* Left to divide with 8192 (2^13) */
|
|
fineFreqOffset = Frac( fineFreqOffset, 8192, FRAC_ROUND );
|
|
/* and to divide with 1000 to get KHz*/
|
|
fineFreqOffset = fineSign * Frac( fineFreqOffset, 1000, FRAC_ROUND ); /* KHz */
|
|
|
|
if ( (rot & 0x8000) == 0x8000 )
|
|
*freqOffset = -(coarseFreqOffset + fineFreqOffset);
|
|
else
|
|
*freqOffset = (coarseFreqOffset + fineFreqOffset);
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t GetOOBFrequency ()
|
|
* \brief Get OOB frequency (Unit:KHz).
|
|
* \param devAddr I2C address
|
|
* \ frequency OOB frequency parameters.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Gets OOB frequency
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetOOBFrequency( pDRXDemodInstance_t demod, pDRXFrequency_t frequency )
|
|
{
|
|
u16_t data = 0;
|
|
DRXFrequency_t freqOffset = 0;
|
|
DRXFrequency_t freq = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
*frequency = 0;/* KHz */
|
|
|
|
SARR16( devAddr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data );
|
|
|
|
freq = (DRXFrequency_t)((DRXFrequency_t)data * 50 + 50000L);
|
|
|
|
CHK_ERROR ( GetOOBFreqOffset ( demod, &freqOffset ) );
|
|
|
|
*frequency = freq + freqOffset;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t GetOOBMER ()
|
|
* \brief Get OOB MER.
|
|
* \param devAddr I2C address
|
|
\ MER OOB parameter in dB.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Gets OOB MER. Table for MER is in Programming guide.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
GetOOBMER( pI2CDeviceAddr_t devAddr, pu32_t mer )
|
|
{
|
|
u16_t data = 0;
|
|
|
|
*mer = 0;
|
|
/* READ MER */
|
|
RR16( devAddr, ORX_EQU_MER_MER_R__A, &data );
|
|
switch (data)
|
|
{
|
|
case 0:/* fall through */
|
|
case 1:
|
|
*mer = 39;
|
|
break;
|
|
case 2:
|
|
*mer = 33;
|
|
break;
|
|
case 3:
|
|
*mer = 29;
|
|
break;
|
|
case 4:
|
|
*mer = 27;
|
|
break;
|
|
case 5:
|
|
*mer = 25;
|
|
break;
|
|
case 6:
|
|
*mer = 23;
|
|
break;
|
|
case 7:
|
|
*mer = 22;
|
|
break;
|
|
case 8:
|
|
*mer = 21;
|
|
break;
|
|
case 9:
|
|
*mer = 20;
|
|
break;
|
|
case 10:
|
|
*mer = 19;
|
|
break;
|
|
case 11:
|
|
*mer = 18;
|
|
break;
|
|
case 12:
|
|
*mer = 17;
|
|
break;
|
|
case 13:/* fall through */
|
|
case 14:
|
|
*mer = 16;
|
|
break;
|
|
case 15:/* fall through */
|
|
case 16:
|
|
*mer = 15;
|
|
break;
|
|
case 17:/* fall through */
|
|
case 18:
|
|
*mer = 14;
|
|
break;
|
|
case 19:/* fall through */
|
|
case 20:
|
|
*mer = 13;
|
|
break;
|
|
case 21:/* fall through */
|
|
case 22:
|
|
*mer = 12;
|
|
break;
|
|
case 23:/* fall through */
|
|
case 24:/* fall through */
|
|
case 25:
|
|
*mer = 11;
|
|
break;
|
|
case 26:/* fall through */
|
|
case 27:/* fall through */
|
|
case 28:
|
|
*mer = 10;
|
|
break;
|
|
case 29:/* fall through */
|
|
case 30:/* fall through */
|
|
case 31:/* fall through */
|
|
case 32:
|
|
*mer = 9;
|
|
break;
|
|
case 33:/* fall through */
|
|
case 34:/* fall through */
|
|
case 35:/* fall through */
|
|
case 36:
|
|
*mer = 8;
|
|
break;
|
|
case 37:/* fall through */
|
|
case 38:/* fall through */
|
|
case 39:/* fall through */
|
|
case 40:
|
|
*mer = 7;
|
|
break;
|
|
case 41:/* fall through */
|
|
case 42:/* fall through */
|
|
case 43:/* fall through */
|
|
case 44:/* fall through */
|
|
case 45:
|
|
*mer = 6;
|
|
break;
|
|
case 46:/* fall through */
|
|
case 47:/* fall through */
|
|
case 48:/* fall through */
|
|
case 49:/* fall through */
|
|
case 50:/* fall through */
|
|
*mer = 5;
|
|
break;
|
|
case 51:/* fall through */
|
|
case 52:/* fall through */
|
|
case 53:/* fall through */
|
|
case 54:/* fall through */
|
|
case 55:/* fall through */
|
|
case 56:/* fall through */
|
|
case 57:
|
|
*mer = 4;
|
|
break;
|
|
case 58:/* fall through */
|
|
case 59:/* fall through */
|
|
case 60:/* fall through */
|
|
case 61:/* fall through */
|
|
case 62:/* fall through */
|
|
case 63:
|
|
*mer = 0;
|
|
break;
|
|
default:
|
|
*mer = 0;
|
|
break;
|
|
}
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif /*#ifndef DRXJ_DIGITAL_ONLY */
|
|
|
|
/**
|
|
* \fn DRXStatus_t SetOrxNsuAox()
|
|
* \brief Configure OrxNsuAox for OOB
|
|
* \param demod instance of demodulator.
|
|
* \param active
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
SetOrxNsuAox ( pDRXDemodInstance_t demod, Bool_t active )
|
|
{
|
|
u16_t data = 0;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Configure NSU_AOX */
|
|
RR16( devAddr, ORX_NSU_AOX_STDBY_W__A , &data );
|
|
if( !active )
|
|
{
|
|
data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON)
|
|
& (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON)
|
|
);
|
|
}
|
|
else /* active */
|
|
{
|
|
data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON
|
|
| ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON
|
|
);
|
|
}
|
|
WR16( devAddr, ORX_NSU_AOX_STDBY_W__A , data );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetOOB()
|
|
* \brief Set OOB channel to be used.
|
|
* \param demod instance of demodulator
|
|
* \param oobParam OOB parameters for channel setting.
|
|
* \frequency should be in KHz
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Accepts only. Returns error otherwise.
|
|
* Demapper value is written after SCUCommand START
|
|
* because START command causes COMM_EXEC transition
|
|
* from 0 to 1 which causes all registers to be
|
|
* overwritten with initial value
|
|
*
|
|
*/
|
|
|
|
/* Nyquist filter impulse response */
|
|
#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 */
|
|
#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 */
|
|
#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) */
|
|
|
|
/* Coefficients for the nyquist fitler (total: 27 taps) */
|
|
#define NYQFILTERLEN 27
|
|
|
|
static DRXStatus_t
|
|
CtrlSetOOB( pDRXDemodInstance_t demod, pDRXOOB_t oobParam )
|
|
{
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
DRXOOBDownstreamStandard_t standard = DRX_OOB_MODE_A;
|
|
DRXFrequency_t freq = 0; /* KHz */
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
u16_t i = 0;
|
|
Bool_t mirrorFreqSpectOOB = FALSE;
|
|
u16_t trkFilterValue = 0;
|
|
DRXJSCUCmd_t scuCmd;
|
|
u16_t setParamParameters[3];
|
|
u16_t cmdResult[2] = {0, 0};
|
|
s16_t NyquistCoeffs[4][(NYQFILTERLEN+1)/2] =
|
|
{
|
|
IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
|
|
IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
|
|
IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
|
|
IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
|
|
};
|
|
u8_t mode_val[4] = {2, 2, 0, 1};
|
|
u8_t PFICoeffs[4][6] =
|
|
{
|
|
{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) */
|
|
{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) */
|
|
{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) */
|
|
{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) */
|
|
};
|
|
u16_t mode_index;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
mirrorFreqSpectOOB = extAttr->mirrorFreqSpectOOB;
|
|
|
|
/* Check parameters */
|
|
if (oobParam == NULL)
|
|
{
|
|
/* power off oob module */
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_STOP;
|
|
scuCmd.parameterLen = 0;
|
|
scuCmd.resultLen = 1;
|
|
scuCmd.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
CHK_ERROR( SetOrxNsuAox( demod, FALSE ) );
|
|
WR16 ( devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
|
|
|
|
extAttr->oobPowerOn = FALSE;
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
standard = oobParam->standard;
|
|
|
|
freq = oobParam->frequency;
|
|
if ((freq < 70000) || (freq > 130000))
|
|
return (DRX_STS_ERROR);
|
|
freq = (freq - 50000) / 50;
|
|
|
|
{
|
|
u16_t index = 0;
|
|
u16_t remainder = 0;
|
|
pu16_t trkFiltercfg = extAttr->oobTrkFilterCfg;
|
|
|
|
index = (u16_t)((freq - 400) / 200);
|
|
remainder = (u16_t)((freq - 400) % 200);
|
|
trkFilterValue = trkFiltercfg[index] - (trkFiltercfg[index] - trkFiltercfg[index + 1])/10
|
|
* remainder / 20;
|
|
}
|
|
|
|
|
|
/*********/
|
|
/* Stop */
|
|
/*********/
|
|
WR16 ( devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_STOP;
|
|
scuCmd.parameterLen = 0;
|
|
scuCmd.resultLen = 1;
|
|
scuCmd.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
/*********/
|
|
/* Reset */
|
|
/*********/
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_RESET;
|
|
scuCmd.parameterLen = 0;
|
|
scuCmd.resultLen = 1;
|
|
scuCmd.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
/***********/
|
|
/* SET_ENV */
|
|
/***********/
|
|
/* set frequency, spectrum inversion and data rate */
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
|
|
scuCmd.parameterLen = 3;
|
|
/* 1-data rate;2-frequency */
|
|
switch ( oobParam->standard )
|
|
{
|
|
case DRX_OOB_MODE_A:
|
|
if(
|
|
/* signal is transmitted inverted */
|
|
( (oobParam->spectrumInverted == TRUE) &
|
|
/* and tuner is not mirroring the signal */
|
|
(mirrorFreqSpectOOB == FALSE) ) |
|
|
/* or */
|
|
/* signal is transmitted noninverted */
|
|
( (oobParam->spectrumInverted == FALSE) &
|
|
/* and tuner is mirroring the signal */
|
|
(mirrorFreqSpectOOB == TRUE) )
|
|
)
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
|
|
else
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
|
|
break;
|
|
case DRX_OOB_MODE_B_GRADE_A:
|
|
if(
|
|
/* signal is transmitted inverted */
|
|
( (oobParam->spectrumInverted == TRUE) &
|
|
/* and tuner is not mirroring the signal */
|
|
(mirrorFreqSpectOOB == FALSE) ) |
|
|
/* or */
|
|
/* signal is transmitted noninverted */
|
|
( (oobParam->spectrumInverted == FALSE) &
|
|
/* and tuner is mirroring the signal */
|
|
(mirrorFreqSpectOOB == TRUE) )
|
|
)
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
|
|
else
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
|
|
break;
|
|
case DRX_OOB_MODE_B_GRADE_B:
|
|
default:
|
|
if(
|
|
/* signal is transmitted inverted */
|
|
( (oobParam->spectrumInverted == TRUE) &
|
|
/* and tuner is not mirroring the signal */
|
|
(mirrorFreqSpectOOB == FALSE) ) |
|
|
/* or */
|
|
/* signal is transmitted noninverted */
|
|
( (oobParam->spectrumInverted == FALSE) &
|
|
/* and tuner is mirroring the signal */
|
|
(mirrorFreqSpectOOB == TRUE) )
|
|
)
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
|
|
else
|
|
setParamParameters[0] = SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
|
|
break;
|
|
}
|
|
setParamParameters[1] = ( u16_t )( freq & 0xFFFF );
|
|
setParamParameters[2] = trkFilterValue;
|
|
scuCmd.parameter = setParamParameters;
|
|
scuCmd.resultLen = 1;
|
|
scuCmd.result = cmdResult;
|
|
mode_index = mode_val[(setParamParameters[0] & 0xC0) >> 6];
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A, 0xFABA); /* Write magic word to enable pdr reg write */
|
|
WR16 ( devAddr, SIO_PDR_OOB_CRX_CFG__A,
|
|
OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B
|
|
| 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B );
|
|
WR16 ( devAddr, SIO_PDR_OOB_DRX_CFG__A,
|
|
OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B
|
|
| 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B );
|
|
WR16 ( devAddr, SIO_TOP_COMM_KEY__A, 0x0000); /* Write magic word to disable pdr reg write */
|
|
|
|
WR16 ( devAddr, ORX_TOP_COMM_KEY__A, 0);
|
|
WR16 ( devAddr, ORX_FWP_AAG_LEN_W__A, 16000);
|
|
WR16 ( devAddr, ORX_FWP_AAG_THR_W__A, 40);
|
|
|
|
/* ddc */
|
|
WR16( devAddr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE);
|
|
|
|
/* nsu */
|
|
WR16( devAddr, ORX_NSU_AOX_LOPOW_W__A, extAttr->oobLoPow);
|
|
|
|
/* initialization for target mode */
|
|
WR16( devAddr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT);
|
|
WR16( devAddr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS);
|
|
|
|
/* Reset bits for timing and freq. recovery */
|
|
WR16( devAddr, SCU_RAM_ORX_RST_CPH__A, 0x0001);
|
|
WR16( devAddr, SCU_RAM_ORX_RST_CTI__A, 0x0002);
|
|
WR16( devAddr, SCU_RAM_ORX_RST_KRN__A, 0x0004);
|
|
WR16( devAddr, SCU_RAM_ORX_RST_KRP__A, 0x0008);
|
|
|
|
/* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
|
|
WR16( devAddr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048>>3);
|
|
WR16( devAddr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16_t) (-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8);
|
|
WR16( devAddr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16_t)(-8));
|
|
WR16( devAddr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1);
|
|
|
|
/* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
|
|
WR16( devAddr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10);
|
|
WR16( devAddr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16_t)(-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8);
|
|
WR16( devAddr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16_t)(-8));
|
|
WR16( devAddr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1<<1);
|
|
|
|
/* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
|
|
WR16( devAddr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17);
|
|
WR16( devAddr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16_t)(-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8);
|
|
WR16( devAddr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16_t)(-8));
|
|
WR16( devAddr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1<<2);
|
|
|
|
/* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
|
|
WR16( devAddr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000);
|
|
WR16( devAddr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16_t)(-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8);
|
|
WR16( devAddr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16_t)(-8));
|
|
WR16( devAddr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1<<3);
|
|
|
|
/* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
|
|
WR16( devAddr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400);
|
|
WR16( devAddr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16_t)(-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8);
|
|
WR16( devAddr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16_t)(-8));
|
|
WR16( devAddr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1<<4);
|
|
|
|
/* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
|
|
WR16( devAddr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20);
|
|
WR16( devAddr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16_t)(-2048));
|
|
WR16( devAddr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4);
|
|
WR16( devAddr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16_t)(-4));
|
|
WR16( devAddr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1<<5);
|
|
|
|
/* PRE-Filter coefficients (PFI) */
|
|
WRB( devAddr, ORX_FWP_PFI_A_W__A, sizeof(PFICoeffs[mode_index]), ((pu8_t)PFICoeffs[mode_index]));
|
|
WR16( devAddr, ORX_TOP_MDE_W__A, mode_index);
|
|
|
|
/* NYQUIST-Filter coefficients (NYQ) */
|
|
for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++)
|
|
{
|
|
WR16( devAddr, ORX_FWP_NYQ_ADR_W__A, i);
|
|
WR16( devAddr, ORX_FWP_NYQ_COF_RW__A, NyquistCoeffs[mode_index][i]);
|
|
}
|
|
WR16( devAddr, ORX_FWP_NYQ_ADR_W__A, 31);
|
|
WR16 ( devAddr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE);
|
|
/*********/
|
|
/* Start */
|
|
/*********/
|
|
scuCmd.command = SCU_RAM_COMMAND_STANDARD_OOB
|
|
| SCU_RAM_COMMAND_CMD_DEMOD_START;
|
|
scuCmd.parameterLen = 0;
|
|
scuCmd.resultLen = 1;
|
|
scuCmd.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &scuCmd ) );
|
|
|
|
CHK_ERROR( SetOrxNsuAox( demod, TRUE ) );
|
|
WR16( devAddr, ORX_NSU_AOX_STHR_W__A, extAttr->oobPreSaw );
|
|
|
|
extAttr->oobPowerOn = TRUE;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
#endif
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetOOB()
|
|
* \brief Set modulation standard to be used.
|
|
* \param demod instance of demodulator
|
|
* \param oobStatus OOB status parameters.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetOOB( pDRXDemodInstance_t demod, pDRXOOBStatus_t oobStatus )
|
|
{
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
u16_t data = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod->myExtAttr;
|
|
|
|
/* check arguments */
|
|
if ( oobStatus == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
if ( extAttr->oobPowerOn == FALSE)
|
|
return (DRX_STS_ERROR);
|
|
|
|
RR16 ( devAddr, ORX_DDC_OFO_SET_W__A, &data);
|
|
RR16 ( devAddr, ORX_NSU_TUN_RFGAIN_W__A, &data);
|
|
RR16 ( devAddr, ORX_FWP_AAG_THR_W__A, &data);
|
|
SARR16 ( devAddr, SCU_RAM_ORX_DGN_KI__A, &data);
|
|
RR16 ( devAddr, ORX_FWP_SRC_DGN_W__A, &data);
|
|
|
|
CHK_ERROR ( GetOOBLockStatus ( demod, devAddr, &oobStatus->lock ));
|
|
CHK_ERROR ( GetOOBFrequency ( demod, &oobStatus->frequency ));
|
|
CHK_ERROR ( GetOOBMER ( devAddr, &oobStatus->mer ));
|
|
CHK_ERROR ( GetOOBSymbolRateOffset ( devAddr, &oobStatus->symbolRateOffset ));
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
#endif
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgOOBPreSAW()
|
|
* \brief Configure PreSAW treshold value
|
|
* \param cfgData Pointer to configuration parameter
|
|
* \return Error code
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
CtrlSetCfgOOBPreSAW( pDRXDemodInstance_t demod, pu16_t cfgData )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
WR16( devAddr, ORX_NSU_AOX_STHR_W__A, *cfgData );
|
|
extAttr->oobPreSaw = *cfgData;
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgOOBPreSAW()
|
|
* \brief Configure PreSAW treshold value
|
|
* \param cfgData Pointer to configuration parameter
|
|
* \return Error code
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
CtrlGetCfgOOBPreSAW( pDRXDemodInstance_t demod, pu16_t cfgData )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
*cfgData = extAttr->oobPreSaw;
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgOOBLoPower()
|
|
* \brief Configure LO Power value
|
|
* \param cfgData Pointer to pDRXJCfgOobLoPower_t
|
|
* \return Error code
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
CtrlSetCfgOOBLoPower( pDRXDemodInstance_t demod, pDRXJCfgOobLoPower_t cfgData )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
devAddr = demod->myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
WR16( devAddr, ORX_NSU_AOX_LOPOW_W__A, *cfgData );
|
|
extAttr->oobLoPow = *cfgData;
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgOOBLoPower()
|
|
* \brief Configure LO Power value
|
|
* \param cfgData Pointer to pDRXJCfgOobLoPower_t
|
|
* \return Error code
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
CtrlGetCfgOOBLoPower( pDRXDemodInstance_t demod, pDRXJCfgOobLoPower_t cfgData )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
if(cfgData == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
*cfgData = extAttr->oobLoPow;
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
#endif
|
|
/*============================================================================*/
|
|
/*== END OOB DATAPATH FUNCTIONS ==*/
|
|
/*============================================================================*/
|
|
|
|
/*=============================================================================
|
|
===== MC command related functions ==========================================
|
|
===========================================================================*/
|
|
|
|
/*=============================================================================
|
|
===== CtrlSetChannel() ==========================================================
|
|
===========================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetChannel()
|
|
* \brief Select a new transmission channel.
|
|
* \param demod instance of demod.
|
|
* \param channel Pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* In case the tuner module is not used and in case of NTSC/FM the pogrammer
|
|
* must tune the tuner to the centre frequency of the NTSC/FM channel.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetChannel( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel )
|
|
{
|
|
|
|
DRXFrequency_t tunerSetFreq = 0;
|
|
DRXFrequency_t tunerGetFreq = 0;
|
|
DRXFrequency_t tunerFreqOffset = 0;
|
|
DRXFrequency_t intermediateFreq = 0;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
TUNERMode_t tunerMode = 0;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
Bool_t bridgeClosed = FALSE;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
u32_t minSymbolRate = 0;
|
|
u32_t maxSymbolRate = 0;
|
|
int bandwidthTemp = 0;
|
|
int bandwidth = 0;
|
|
#endif
|
|
/*== check arguments ======================================================*/
|
|
if ( ( demod == NULL ) ||
|
|
( channel == NULL ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
standard = extAttr->standard;
|
|
|
|
/* check valid standards */
|
|
switch ( standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif /* DRXJ_VSB_ONLY */
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_FM:
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
#endif /* DRXJ_DIGITAL_ONLY */
|
|
break;
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* check bandwidth QAM annex B, NTSC and 8VSB */
|
|
if ( ( standard == DRX_STANDARD_ITU_B ) ||
|
|
( standard == DRX_STANDARD_8VSB ) ||
|
|
( standard == DRX_STANDARD_NTSC ) )
|
|
{
|
|
switch ( channel->bandwidth ) {
|
|
case DRX_BANDWIDTH_6MHZ :
|
|
case DRX_BANDWIDTH_UNKNOWN : /* fall through */
|
|
channel->bandwidth = DRX_BANDWIDTH_6MHZ;
|
|
break;
|
|
case DRX_BANDWIDTH_8MHZ : /* fall through */
|
|
case DRX_BANDWIDTH_7MHZ : /* fall through */
|
|
default :
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
if ( standard == DRX_STANDARD_PAL_SECAM_BG )
|
|
{
|
|
switch ( channel->bandwidth )
|
|
{
|
|
case DRX_BANDWIDTH_7MHZ : /* fall through */
|
|
case DRX_BANDWIDTH_8MHZ :
|
|
/* ok */
|
|
break;
|
|
case DRX_BANDWIDTH_6MHZ : /* fall through */
|
|
case DRX_BANDWIDTH_UNKNOWN : /* fall through */
|
|
default :
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
/* check bandwidth PAL/SECAM */
|
|
if ( ( standard == DRX_STANDARD_PAL_SECAM_BG ) ||
|
|
( standard == DRX_STANDARD_PAL_SECAM_DK ) ||
|
|
( standard == DRX_STANDARD_PAL_SECAM_I ) ||
|
|
( standard == DRX_STANDARD_PAL_SECAM_L ) ||
|
|
( standard == DRX_STANDARD_PAL_SECAM_LP ) )
|
|
{
|
|
switch ( channel->bandwidth )
|
|
{
|
|
case DRX_BANDWIDTH_8MHZ :
|
|
case DRX_BANDWIDTH_UNKNOWN : /* fall through */
|
|
channel->bandwidth = DRX_BANDWIDTH_8MHZ;
|
|
break;
|
|
case DRX_BANDWIDTH_6MHZ : /* fall through */
|
|
case DRX_BANDWIDTH_7MHZ : /* fall through */
|
|
default :
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* For QAM annex A and annex C:
|
|
-check symbolrate and constellation
|
|
-derive bandwidth from symbolrate (input bandwidth is ignored)
|
|
*/
|
|
#ifndef DRXJ_VSB_ONLY
|
|
if( ( standard == DRX_STANDARD_ITU_A ) ||
|
|
( standard == DRX_STANDARD_ITU_C ) )
|
|
{
|
|
DRXUIOCfg_t UIOCfg = {DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW};
|
|
int bwRolloffFactor = 0;
|
|
|
|
bwRolloffFactor = (standard == DRX_STANDARD_ITU_A)?115:113;
|
|
minSymbolRate = DRXJ_QAM_SYMBOLRATE_MIN;
|
|
maxSymbolRate = DRXJ_QAM_SYMBOLRATE_MAX;
|
|
/* config SMA_TX pin to SAW switch mode*/
|
|
CHK_ERROR( CtrlSetUIOCfg( demod, &UIOCfg ) );
|
|
|
|
if ( channel->symbolrate < minSymbolRate ||
|
|
channel->symbolrate > maxSymbolRate )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_QAM16 : /* fall through */
|
|
case DRX_CONSTELLATION_QAM32 : /* fall through */
|
|
case DRX_CONSTELLATION_QAM64 : /* fall through */
|
|
case DRX_CONSTELLATION_QAM128 : /* fall through */
|
|
case DRX_CONSTELLATION_QAM256 :
|
|
bandwidthTemp = channel->symbolrate * bwRolloffFactor;
|
|
bandwidth = bandwidthTemp / 100;
|
|
|
|
if( ( bandwidthTemp % 100 ) >= 50 )
|
|
{
|
|
bandwidth++;
|
|
}
|
|
|
|
if( bandwidth <= 6100000 )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_6MHZ;
|
|
}
|
|
else if( ( bandwidth > 6100000 ) && ( bandwidth <= 7100000 ) )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_7MHZ;
|
|
}
|
|
else if( bandwidth > 7100000 )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_8MHZ;
|
|
}
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
|
|
/* For QAM annex B:
|
|
-check constellation
|
|
*/
|
|
if ( standard == DRX_STANDARD_ITU_B )
|
|
{
|
|
switch ( channel->constellation ) {
|
|
case DRX_CONSTELLATION_AUTO :
|
|
case DRX_CONSTELLATION_QAM256 :
|
|
case DRX_CONSTELLATION_QAM64 :
|
|
break;
|
|
default :
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
switch (channel->interleavemode)
|
|
{
|
|
case DRX_INTERLEAVEMODE_I128_J1:
|
|
case DRX_INTERLEAVEMODE_I128_J1_V2:
|
|
case DRX_INTERLEAVEMODE_I128_J2:
|
|
case DRX_INTERLEAVEMODE_I64_J2:
|
|
case DRX_INTERLEAVEMODE_I128_J3:
|
|
case DRX_INTERLEAVEMODE_I32_J4:
|
|
case DRX_INTERLEAVEMODE_I128_J4:
|
|
case DRX_INTERLEAVEMODE_I16_J8:
|
|
case DRX_INTERLEAVEMODE_I128_J5:
|
|
case DRX_INTERLEAVEMODE_I8_J16:
|
|
case DRX_INTERLEAVEMODE_I128_J6:
|
|
case DRX_INTERLEAVEMODE_I128_J7:
|
|
case DRX_INTERLEAVEMODE_I128_J8:
|
|
case DRX_INTERLEAVEMODE_I12_J17:
|
|
case DRX_INTERLEAVEMODE_I5_J4:
|
|
case DRX_INTERLEAVEMODE_B52_M240:
|
|
case DRX_INTERLEAVEMODE_B52_M720:
|
|
case DRX_INTERLEAVEMODE_UNKNOWN:
|
|
case DRX_INTERLEAVEMODE_AUTO:
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
}
|
|
|
|
if ( (extAttr->uioSmaTxMode) == DRX_UIO_MODE_FIRMWARE_SAW )
|
|
{
|
|
/* SAW SW, user UIO is used for switchable SAW */
|
|
DRXUIOData_t uio1 = { DRX_UIO1, FALSE };
|
|
|
|
switch ( channel->bandwidth )
|
|
{
|
|
case DRX_BANDWIDTH_8MHZ:
|
|
uio1.value = TRUE;
|
|
break;
|
|
case DRX_BANDWIDTH_7MHZ:
|
|
uio1.value = FALSE;
|
|
break;
|
|
case DRX_BANDWIDTH_6MHZ:
|
|
uio1.value = FALSE;
|
|
break;
|
|
case DRX_BANDWIDTH_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
CHK_ERROR( CtrlUIOWrite( demod, &uio1 ) );
|
|
}
|
|
#endif /* DRXJ_VSB_ONLY */
|
|
WR16( devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
|
|
/*== Tune, fast mode ======================================================*/
|
|
if ( demod->myTuner != NULL )
|
|
{
|
|
/* Determine tuner mode and freq to tune to ... */
|
|
switch ( standard ) {
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
/* expecting center frequency, not picture carrier so no
|
|
conversion .... */
|
|
tunerMode |= TUNER_MODE_ANALOG;
|
|
tunerSetFreq = channel->frequency;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
/* center frequency (equals sound carrier) as input,
|
|
tune to edge of SAW */
|
|
tunerMode |= TUNER_MODE_ANALOG;
|
|
tunerSetFreq = channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
tunerMode |= TUNER_MODE_DIGITAL;
|
|
tunerSetFreq = channel->frequency;
|
|
break;
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* switch(standard) */
|
|
|
|
tunerMode |= TUNER_MODE_SWITCH;
|
|
switch ( channel->bandwidth ) {
|
|
case DRX_BANDWIDTH_8MHZ :
|
|
tunerMode |= TUNER_MODE_8MHZ;
|
|
break;
|
|
case DRX_BANDWIDTH_7MHZ :
|
|
tunerMode |= TUNER_MODE_7MHZ;
|
|
break;
|
|
case DRX_BANDWIDTH_6MHZ :
|
|
tunerMode |= TUNER_MODE_6MHZ;
|
|
break;
|
|
default:
|
|
/* TODO: for FM which bandwidth to use ?
|
|
also check offset from centre frequency ?
|
|
For now using 6MHz.
|
|
*/
|
|
tunerMode |= TUNER_MODE_6MHZ;
|
|
break;
|
|
/* return (DRX_STS_INVALID_ARG); */
|
|
}
|
|
|
|
/* store bandwidth for GetChannel() */
|
|
extAttr->currBandwidth = channel->bandwidth;
|
|
extAttr->currSymbolRate = channel->symbolrate;
|
|
extAttr->frequency = tunerSetFreq;
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
/* close tuner bridge */
|
|
bridgeClosed = TRUE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
/* set tuner frequency */
|
|
}
|
|
|
|
CHK_ERROR( DRXBSP_TUNER_SetFrequency( demod->myTuner,
|
|
tunerMode,
|
|
tunerSetFreq ) );
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
/* open tuner bridge */
|
|
bridgeClosed = FALSE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
|
|
/* Get actual frequency set by tuner and compute offset */
|
|
CHK_ERROR( DRXBSP_TUNER_GetFrequency( demod->myTuner,
|
|
0,
|
|
&tunerGetFreq,
|
|
&intermediateFreq ) );
|
|
tunerFreqOffset = tunerGetFreq - tunerSetFreq;
|
|
commonAttr->intermediateFreq = intermediateFreq;
|
|
}
|
|
else
|
|
{
|
|
/* no tuner instance defined, use fixed intermediate frequency */
|
|
tunerFreqOffset = 0;
|
|
intermediateFreq = demod->myCommonAttr->intermediateFreq;
|
|
} /* if ( demod->myTuner != NULL ) */
|
|
|
|
/*== Setup demod for specific standard ====================================*/
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB:
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
CHK_ERROR ( SetVSB(demod) );
|
|
CHK_ERROR ( SetFrequency ( demod, channel, tunerFreqOffset ) );
|
|
break;
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
if (channel->mirror == DRX_MIRROR_AUTO)
|
|
{
|
|
extAttr->mirror = DRX_MIRROR_NO;
|
|
}
|
|
else
|
|
{
|
|
extAttr->mirror = channel->mirror;
|
|
}
|
|
CHK_ERROR ( SetATVChannel( demod,
|
|
tunerFreqOffset,
|
|
channel,
|
|
standard ) );
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
CHK_ERROR ( SetQAMChannel( demod, channel, tunerFreqOffset ) );
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*== Re-tune, slow mode ===================================================*/
|
|
if ( demod->myTuner != NULL )
|
|
{
|
|
/* tune to slow mode */
|
|
tunerMode &= ~TUNER_MODE_SWITCH;
|
|
tunerMode |= TUNER_MODE_LOCK;
|
|
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
/* close tuner bridge */
|
|
bridgeClosed = TRUE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
|
|
/* set tuner frequency*/
|
|
CHK_ERROR( DRXBSP_TUNER_SetFrequency( demod->myTuner,
|
|
tunerMode,
|
|
tunerSetFreq ) );
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
/* open tuner bridge */
|
|
bridgeClosed = FALSE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
} /* if ( demod->myTuner !=NULL ) */
|
|
|
|
/* flag the packet error counter reset */
|
|
extAttr->resetPktErrAcc = TRUE;
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*=============================================================================
|
|
===== CtrlGetChannel() ==========================================================
|
|
===========================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetChannel()
|
|
* \brief Retreive parameters of current transmission channel.
|
|
* \param demod Pointer to demod instance.
|
|
* \param channel Pointer to channel data.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetChannel( pDRXDemodInstance_t demod,
|
|
pDRXChannel_t channel )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
DRXFrequency_t intermediateFreq = 0;
|
|
s32_t CTLFreqOffset = 0;
|
|
u32_t iqmRcRateLo = 0;
|
|
u32_t adcFrequency = 0;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
int bandwidthTemp = 0;
|
|
int bandwidth = 0;
|
|
#endif
|
|
|
|
/* check arguments */
|
|
if ( ( demod == NULL ) ||
|
|
( channel == NULL ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
standard = extAttr->standard;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
/* initialize channel fields */
|
|
channel->mirror = DRX_MIRROR_UNKNOWN;
|
|
channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
|
|
channel->priority = DRX_PRIORITY_UNKNOWN;
|
|
channel->coderate = DRX_CODERATE_UNKNOWN;
|
|
channel->guard = DRX_GUARD_UNKNOWN;
|
|
channel->fftmode = DRX_FFTMODE_UNKNOWN;
|
|
channel->classification = DRX_CLASSIFICATION_UNKNOWN;
|
|
channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
|
|
channel->constellation = DRX_CONSTELLATION_UNKNOWN;
|
|
channel->symbolrate = 0;
|
|
channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
|
|
channel->carrier = DRX_CARRIER_UNKNOWN;
|
|
channel->framemode = DRX_FRAMEMODE_UNKNOWN;
|
|
/* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
|
|
channel->ldpc = DRX_LDPC_UNKNOWN;
|
|
|
|
if ( demod->myTuner != NULL )
|
|
{
|
|
DRXFrequency_t tunerFreqOffset = 0;
|
|
Bool_t tunerMirror = commonAttr->mirrorFreqSpect?FALSE:TRUE;
|
|
|
|
/* Get frequency from tuner */
|
|
CHK_ERROR( DRXBSP_TUNER_GetFrequency( demod->myTuner,
|
|
0,
|
|
&(channel->frequency),
|
|
&intermediateFreq ) );
|
|
tunerFreqOffset = channel->frequency - extAttr->frequency;
|
|
if ( tunerMirror == TRUE )
|
|
{
|
|
/* positive image */
|
|
channel->frequency += tunerFreqOffset;
|
|
} else {
|
|
/* negative image */
|
|
channel->frequency -= tunerFreqOffset;
|
|
}
|
|
|
|
/* Handle sound carrier offset in RF domain */
|
|
if ( standard == DRX_STANDARD_FM )
|
|
{
|
|
channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
intermediateFreq = commonAttr->intermediateFreq;
|
|
}
|
|
|
|
/* check lock status */
|
|
CHK_ERROR( CtrlLockStatus( demod, &lockStatus) );
|
|
if ( (lockStatus == DRX_LOCKED) || (lockStatus == DRXJ_DEMOD_LOCK) )
|
|
{
|
|
ARR32( devAddr, IQM_RC_RATE_LO__A, &iqmRcRateLo );
|
|
adcFrequency = ( commonAttr->sysClockFreq * 1000 ) / 3;
|
|
|
|
channel->symbolrate = Frac28(adcFrequency, (iqmRcRateLo + (1<<23))) >> 7;
|
|
|
|
switch ( standard )
|
|
{
|
|
case DRX_STANDARD_8VSB:
|
|
channel->bandwidth = DRX_BANDWIDTH_6MHZ;
|
|
/* get the channel frequency */
|
|
CHK_ERROR( GetCTLFreqOffset ( demod, &CTLFreqOffset ) );
|
|
channel->frequency -= CTLFreqOffset;
|
|
/* get the channel constellation */
|
|
channel->constellation = DRX_CONSTELLATION_AUTO;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
{
|
|
/* get the channel frequency */
|
|
CHK_ERROR( GetCTLFreqOffset ( demod, &CTLFreqOffset ) );
|
|
channel->frequency -= CTLFreqOffset;
|
|
|
|
if (standard == DRX_STANDARD_ITU_B)
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_6MHZ;
|
|
}
|
|
else
|
|
{
|
|
/* annex A & C */
|
|
|
|
u32_t rollOff=113; /* default annex C */
|
|
|
|
if ( standard==DRX_STANDARD_ITU_A)
|
|
{
|
|
rollOff=115;
|
|
}
|
|
|
|
bandwidthTemp = channel->symbolrate * rollOff;
|
|
bandwidth = bandwidthTemp / 100;
|
|
|
|
if( ( bandwidthTemp % 100 ) >= 50 )
|
|
{
|
|
bandwidth++;
|
|
}
|
|
|
|
if( bandwidth <= 6000000 )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_6MHZ;
|
|
}
|
|
else if( ( bandwidth > 6000000 ) && ( bandwidth <= 7000000 ) )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_7MHZ;
|
|
}
|
|
else if( bandwidth > 7000000 )
|
|
{
|
|
channel->bandwidth = DRX_BANDWIDTH_8MHZ;
|
|
}
|
|
} /* if (standard == DRX_STANDARD_ITU_B) */
|
|
|
|
{
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* parameter */ NULL,
|
|
/* result */ NULL };
|
|
u16_t cmdResult[3] = { 0, 0, 0 };
|
|
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 3;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
channel->interleavemode = (DRXInterleaveModes_t)(cmdSCU.result[2]);
|
|
}
|
|
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
channel->constellation = DRX_CONSTELLATION_QAM256;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
channel->constellation = DRX_CONSTELLATION_QAM128;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
channel->constellation = DRX_CONSTELLATION_QAM64;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
channel->constellation = DRX_CONSTELLATION_QAM32;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM16:
|
|
channel->constellation = DRX_CONSTELLATION_QAM16;
|
|
break;
|
|
default:
|
|
channel->constellation = DRX_CONSTELLATION_UNKNOWN;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC: /* fall trough */
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_FM:
|
|
CHK_ERROR( GetATVChannel(demod, channel, standard));
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN: /* fall trough */
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
} /* switch ( standard ) */
|
|
|
|
if (lockStatus == DRX_LOCKED)
|
|
{
|
|
channel->mirror = extAttr->mirror;
|
|
}
|
|
} /* if ( lockStatus == DRX_LOCKED ) */
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*=============================================================================
|
|
===== SigQuality() ==========================================================
|
|
===========================================================================*/
|
|
|
|
static u16_t
|
|
mer2indicator (
|
|
u16_t mer,
|
|
u16_t minMer,
|
|
u16_t thresholdMer,
|
|
u16_t maxMer)
|
|
{
|
|
u16_t indicator = 0;
|
|
|
|
if ( mer < minMer )
|
|
{
|
|
indicator = 0;
|
|
}
|
|
else if ( mer < thresholdMer )
|
|
{
|
|
if ((thresholdMer - minMer) != 0)
|
|
{
|
|
indicator = 25 * (mer - minMer) / (thresholdMer - minMer);
|
|
}
|
|
}
|
|
else if ( mer < maxMer )
|
|
{
|
|
if ((maxMer - thresholdMer) != 0)
|
|
{
|
|
indicator = 25 + 75 * (mer - thresholdMer) / (maxMer - thresholdMer);
|
|
}
|
|
else
|
|
{
|
|
indicator = 25;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
indicator = 100;
|
|
}
|
|
|
|
return indicator;
|
|
}
|
|
/**
|
|
* \fn DRXStatus_t CtrlSigQuality()
|
|
* \brief Retreive signal quality form device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param sigQuality Pointer to signal quality data.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigQuality contains valid data.
|
|
* \retval DRX_STS_INVALID_ARG sigQuality is NULL.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigQuality contains invalid data.
|
|
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSigQuality( pDRXDemodInstance_t demod,
|
|
pDRXSigQuality_t sigQuality )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
u16_t minMer = 0;
|
|
u16_t maxMer = 0;
|
|
u16_t thresholdMer = 0;
|
|
|
|
/* Check arguments */
|
|
if (( sigQuality == NULL ) ||
|
|
( demod == NULL ))
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
standard = extAttr->standard;
|
|
|
|
/* get basic information */
|
|
devAddr = demod -> myI2CDevAddr;
|
|
CHK_ERROR( CtrlLockStatus( demod, &lockStatus) );
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB:
|
|
#ifdef DRXJ_SIGNAL_ACCUM_ERR
|
|
CHK_ERROR (GetAccPktErr (demod, &sigQuality->packetError));
|
|
#else
|
|
CHK_ERROR (GetVSBPostRSPckErr (devAddr, &sigQuality->packetError));
|
|
#endif
|
|
if ( lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED )
|
|
{
|
|
sigQuality->postViterbiBER = 500000;
|
|
sigQuality->MER = 20;
|
|
sigQuality->preViterbiBER = 0;
|
|
} else {
|
|
/* PostViterbi is compute in steps of 10^(-6) */
|
|
CHK_ERROR (GetVSBpreViterbiBer (devAddr, &sigQuality->preViterbiBER));
|
|
CHK_ERROR (GetVSBpostViterbiBer (devAddr, &sigQuality->postViterbiBER));
|
|
CHK_ERROR (GetVSBMER (devAddr, &sigQuality->MER));
|
|
}
|
|
minMer = 20;
|
|
maxMer = 360;
|
|
thresholdMer = 145;
|
|
sigQuality->postReedSolomonBER = 0;
|
|
sigQuality->scaleFactorBER = 1000000;
|
|
sigQuality->indicator = mer2indicator (sigQuality->MER, minMer, thresholdMer, maxMer);
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
CHK_ERROR ( CtrlGetQAMSigQuality ( demod, sigQuality ) );
|
|
if ( lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED )
|
|
{
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
sigQuality->MER = 210;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
sigQuality->MER = 180;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
sigQuality->MER = 150;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM32:
|
|
sigQuality->MER = 120;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM16:
|
|
sigQuality->MER = 90;
|
|
break;
|
|
default:
|
|
sigQuality->MER = 0;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
}
|
|
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
minMer = 210;
|
|
thresholdMer = 270;
|
|
maxMer = 380;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
minMer = 150;
|
|
thresholdMer = 210;
|
|
maxMer = 380;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM128:
|
|
case DRX_CONSTELLATION_QAM32:
|
|
case DRX_CONSTELLATION_QAM16:
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
sigQuality->indicator = mer2indicator (sigQuality->MER, minMer, thresholdMer, maxMer);
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
case DRX_STANDARD_NTSC:
|
|
CHK_ERROR ( AtvSigQuality ( demod, sigQuality ) );
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
CHK_ERROR ( FmSigQuality ( demod, sigQuality ) );
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlLockStatus()
|
|
* \brief Retreive lock status .
|
|
* \param devAddr Pointer to demodulator device address.
|
|
* \param lockStat Pointer to lock status structure.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlLockStatus( pDRXDemodInstance_t demod,
|
|
pDRXLockStatus_t lockStat )
|
|
{
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
pDRXJData_t extAttr = NULL;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXJSCUCmd_t cmdSCU = { /* command */ 0,
|
|
/* parameterLen */ 0,
|
|
/* resultLen */ 0,
|
|
/* *parameter */ NULL,
|
|
/* *result */ NULL };
|
|
u16_t cmdResult[2] = { 0, 0 };
|
|
u16_t demodLock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
|
|
|
|
/* check arguments */
|
|
if ( ( demod == NULL ) ||
|
|
( lockStat == NULL ) )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
standard = extAttr->standard;
|
|
|
|
*lockStat = DRX_NOT_LOCKED;
|
|
|
|
/* define the SCU command code */
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB:
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_VSB |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
|
|
demodLock |= 0x6;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_QAM |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_PAL_SECAM_BG:
|
|
case DRX_STANDARD_PAL_SECAM_DK:
|
|
case DRX_STANDARD_PAL_SECAM_I:
|
|
case DRX_STANDARD_PAL_SECAM_L:
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
cmdSCU.command = SCU_RAM_COMMAND_STANDARD_ATV |
|
|
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
return FmLockStatus( demod, lockStat);
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN: /* fallthrough */
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/* define the SCU command paramters and execute the command */
|
|
cmdSCU.parameterLen = 0;
|
|
cmdSCU.resultLen = 2;
|
|
cmdSCU.parameter = NULL;
|
|
cmdSCU.result = cmdResult;
|
|
CHK_ERROR( SCUCommand( devAddr, &cmdSCU ) );
|
|
|
|
/* set the lock status */
|
|
if ( cmdSCU.result[1] < demodLock )
|
|
{
|
|
/* 0x0000 NOT LOCKED */
|
|
*lockStat = DRX_NOT_LOCKED;
|
|
}
|
|
else if ( cmdSCU.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED )
|
|
{
|
|
*lockStat = DRXJ_DEMOD_LOCK;
|
|
}
|
|
else if ( cmdSCU.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK )
|
|
{
|
|
/* 0x8000 DEMOD + FEC LOCKED (system lock) */
|
|
*lockStat = DRX_LOCKED;
|
|
}
|
|
else
|
|
{
|
|
/* 0xC000 NEVER LOCKED */
|
|
/* (system will never be able to lock to the signal) */
|
|
*lockStat = DRX_NEVER_LOCK;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlConstel()
|
|
* \brief Retreive a constellation point via I2C.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param complexNr Pointer to the structure in which to store the
|
|
constellation point.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlConstel( pDRXDemodInstance_t demod,
|
|
pDRXComplex_t complexNr )
|
|
{
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN; /**< active standard */
|
|
|
|
/* check arguments */
|
|
if ( ( demod == NULL ) ||
|
|
( complexNr == NULL ) )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* read device info */
|
|
standard = ((pDRXJData_t)demod->myExtAttr)->standard;
|
|
|
|
/* Read constellation point */
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB:
|
|
CHK_ERROR( CtrlGetVSBConstel( demod, complexNr ) );
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
CHK_ERROR( CtrlGetQAMConstel( demod, complexNr ) );
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetStandard()
|
|
* \brief Set modulation standard to be used.
|
|
* \param standard Modulation standard.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Setup stuff for the desired demodulation standard.
|
|
* Disable and power down the previous selected demodulation standard
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetStandard( pDRXDemodInstance_t demod, pDRXStandard_t standard )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t prevStandard;
|
|
|
|
/* check arguments */
|
|
if (( standard == NULL ) ||
|
|
( demod == NULL ))
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
prevStandard=extAttr->standard;
|
|
|
|
/*
|
|
Stop and power down previous standard
|
|
*/
|
|
switch ( prevStandard )
|
|
{
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
CHK_ERROR( PowerDownQAM(demod, FALSE) );
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_8VSB:
|
|
CHK_ERROR( PowerDownVSB(demod, FALSE) );
|
|
break;
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
CHK_ERROR( PowerDownATV( demod, prevStandard, FALSE ));
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN:
|
|
/* Do nothing */
|
|
break;
|
|
case DRX_STANDARD_AUTO: /* fallthrough */
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/*
|
|
Initialize channel independent registers
|
|
Power up new standard
|
|
*/
|
|
extAttr->standard=*standard;
|
|
|
|
switch ( *standard )
|
|
{
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
DUMMY_READ();
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_8VSB:
|
|
CHK_ERROR(SetVSBLeakNGain(demod));
|
|
break;
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP:
|
|
CHK_ERROR( SetATVStandard( demod, standard ));
|
|
CHK_ERROR( PowerUpATV( demod, *standard ));
|
|
break;
|
|
#endif
|
|
default:
|
|
extAttr->standard=DRX_STANDARD_UNKNOWN;
|
|
return ( DRX_STS_INVALID_ARG );
|
|
break;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
/* Don't know what the standard is now ... try again */
|
|
extAttr->standard=DRX_STANDARD_UNKNOWN;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetStandard()
|
|
* \brief Get modulation standard currently used to demodulate.
|
|
* \param standard Modulation standard.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Returns 8VSB, NTSC, QAM only.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetStandard( pDRXDemodInstance_t demod, pDRXStandard_t standard )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* check arguments */
|
|
if ( standard == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
(*standard) = extAttr->standard;
|
|
DUMMY_READ();
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgSymbolClockOffset()
|
|
* \brief Get frequency offsets of STR.
|
|
* \param pointer to s32_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgSymbolClockOffset ( pDRXDemodInstance_t demod,
|
|
ps32_t rateOffset )
|
|
{
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* check arguments */
|
|
if ( rateOffset == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
standard = extAttr->standard;
|
|
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
CHK_ERROR ( GetSTRFreqOffset ( demod, rateOffset ));
|
|
break;
|
|
case DRX_STANDARD_NTSC:
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlPowerMode()
|
|
* \brief Set the power mode of the device to the specified power mode
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param mode Pointer to new power mode.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK Success
|
|
* \retval DRX_STS_ERROR I2C error or other failure
|
|
* \retval DRX_STS_INVALID_ARG Invalid mode argument.
|
|
*
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlPowerMode( pDRXDemodInstance_t demod,
|
|
pDRXPowerMode_t mode )
|
|
{
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)NULL;
|
|
pDRXJData_t extAttr = (pDRXJData_t)NULL;
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)NULL;
|
|
u16_t sioCcPwdMode = 0;
|
|
|
|
commonAttr = (pDRXCommonAttr_t)demod -> myCommonAttr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Check arguments */
|
|
if ( mode == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* If already in requested power mode, do nothing */
|
|
if ( commonAttr->currentPowerMode == *mode )
|
|
{
|
|
return (DRX_STS_OK);
|
|
}
|
|
|
|
switch ( *mode )
|
|
{
|
|
case DRX_POWER_UP:
|
|
case DRXJ_POWER_DOWN_MAIN_PATH:
|
|
sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
|
|
break;
|
|
case DRXJ_POWER_DOWN_CORE:
|
|
sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
|
|
break;
|
|
case DRXJ_POWER_DOWN_PLL:
|
|
sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
|
|
break;
|
|
case DRX_POWER_DOWN:
|
|
sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
|
|
break;
|
|
default:
|
|
/* Unknow sleep mode */
|
|
return (DRX_STS_INVALID_ARG);
|
|
break;
|
|
}
|
|
|
|
|
|
/* Check if device needs to be powered up */
|
|
if ( ( commonAttr->currentPowerMode != DRX_POWER_UP ) )
|
|
{
|
|
CHK_ERROR(PowerUpDevice(demod));
|
|
}
|
|
|
|
if ( ( *mode == DRX_POWER_UP ) )
|
|
{
|
|
/* Restore analog & pin configuartion */
|
|
} else {
|
|
/* Power down to requested mode */
|
|
/* Backup some register settings */
|
|
/* Set pins with possible pull-ups connected to them in input mode */
|
|
/* Analog power down */
|
|
/* ADC power down */
|
|
/* Power down device */
|
|
/* stop all comm_exec */
|
|
/*
|
|
Stop and power down previous standard
|
|
*/
|
|
|
|
switch ( extAttr->standard )
|
|
{
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
CHK_ERROR( PowerDownQAM(demod, TRUE) );
|
|
break;
|
|
case DRX_STANDARD_8VSB:
|
|
CHK_ERROR( PowerDownVSB(demod, TRUE) );
|
|
break;
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
CHK_ERROR( PowerDownATV( demod, extAttr->standard, TRUE ));
|
|
break;
|
|
case DRX_STANDARD_UNKNOWN:
|
|
/* Do nothing */
|
|
break;
|
|
case DRX_STANDARD_AUTO: /* fallthrough */
|
|
default:
|
|
return ( DRX_STS_ERROR );
|
|
}
|
|
|
|
if (*mode != DRXJ_POWER_DOWN_MAIN_PATH)
|
|
{
|
|
WR16( devAddr, SIO_CC_PWD_MODE__A, sioCcPwdMode);
|
|
WR16( devAddr, SIO_CC_UPDATE__A , SIO_CC_UPDATE_KEY);
|
|
|
|
/* Initialize HI, wakeup key especially before put IC to sleep */
|
|
CHK_ERROR(InitHI(demod) );
|
|
|
|
extAttr -> HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
|
|
CHK_ERROR( HICfgCommand( demod ) );
|
|
}
|
|
}
|
|
|
|
commonAttr->currentPowerMode = *mode;
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlVersion()
|
|
* \brief Report version of microcode and if possible version of device
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param versionList Pointer to pointer of linked list of versions.
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Using static structures so no allocation of memory is needed.
|
|
* Filling in all the fields each time, cause you don't know if they are
|
|
* changed by the application.
|
|
*
|
|
* For device:
|
|
* Major version number will be last two digits of family number.
|
|
* Minor number will be full respin number
|
|
* Patch will be metal fix number+1
|
|
* Examples:
|
|
* DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
|
|
* DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlVersion( pDRXDemodInstance_t demod,
|
|
pDRXVersionList_t *versionList )
|
|
{
|
|
pDRXJData_t extAttr = (pDRXJData_t) (NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t) (NULL);
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)(NULL);
|
|
u16_t ucodeMajorMinor = 0; /* BCD Ma:Ma:Ma:Mi */
|
|
u16_t ucodePatch = 0; /* BCD Pa:Pa:Pa:Pa */
|
|
u16_t major = 0;
|
|
u16_t minor = 0;
|
|
u16_t patch = 0;
|
|
u16_t idx = 0;
|
|
u32_t jtag = 0;
|
|
u16_t subtype = 0;
|
|
u16_t mfx = 0;
|
|
u16_t bid = 0;
|
|
u16_t key = 0;
|
|
|
|
static char ucodeName[] = "Microcode";
|
|
static char deviceName[] = "Device";
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t)demod->myCommonAttr;
|
|
|
|
/* Microcode version ****************************************/
|
|
|
|
extAttr->vVersion[0].moduleType = DRX_MODULE_MICROCODE;
|
|
extAttr->vVersion[0].moduleName = ucodeName;
|
|
extAttr->vVersion[0].vString = extAttr->vText[0];
|
|
|
|
if ( commonAttr->isOpened == TRUE )
|
|
{
|
|
SARR16( devAddr, SCU_RAM_VERSION_HI__A, &ucodeMajorMinor );
|
|
SARR16( devAddr, SCU_RAM_VERSION_LO__A, &ucodePatch );
|
|
|
|
/* Translate BCD to numbers and string */
|
|
/* TODO: The most significant Ma and Pa will be ignored, check with spec */
|
|
minor = (ucodeMajorMinor & 0xF);
|
|
ucodeMajorMinor >>= 4;
|
|
major = (ucodeMajorMinor & 0xF);
|
|
ucodeMajorMinor >>= 4;
|
|
major += (10* (ucodeMajorMinor & 0xF));
|
|
patch = (ucodePatch & 0xF);
|
|
ucodePatch >>= 4;
|
|
patch += (10*(ucodePatch & 0xF));
|
|
ucodePatch >>= 4;
|
|
patch += (100*(ucodePatch & 0xF));
|
|
}
|
|
else
|
|
{
|
|
/* No microcode uploaded, No Rom existed, set version to 0.0.0 */
|
|
patch = 0;
|
|
minor = 0;
|
|
major = 0;
|
|
}
|
|
extAttr->vVersion[0].vMajor = major;
|
|
extAttr->vVersion[0].vMinor = minor;
|
|
extAttr->vVersion[0].vPatch = patch;
|
|
|
|
if ( major/10 != 0 )
|
|
{
|
|
extAttr->vVersion[0].vString[idx++] = ((char)(major/10))+'0';
|
|
major %= 10;
|
|
}
|
|
extAttr->vVersion[0].vString[idx++] = ((char)major)+'0';
|
|
extAttr->vVersion[0].vString[idx++] = '.';
|
|
extAttr->vVersion[0].vString[idx++] = ((char)minor)+'0';
|
|
extAttr->vVersion[0].vString[idx++] = '.';
|
|
if ( patch/100 != 0 )
|
|
{
|
|
extAttr->vVersion[0].vString[idx++] = ((char)(patch/100))+'0';
|
|
patch %= 100;
|
|
}
|
|
if ( patch/10 != 0 )
|
|
{
|
|
extAttr->vVersion[0].vString[idx++] = ((char)(patch/10))+'0';
|
|
patch %= 10;
|
|
}
|
|
extAttr->vVersion[0].vString[idx++] = ((char)patch)+'0';
|
|
extAttr->vVersion[0].vString[idx] = '\0';
|
|
|
|
extAttr->vListElements[0].version = &(extAttr->vVersion[0]);
|
|
extAttr->vListElements[0].next = &(extAttr->vListElements[1]);
|
|
|
|
|
|
/* Device version ****************************************/
|
|
/* Check device id */
|
|
RR16( devAddr, SIO_TOP_COMM_KEY__A , &key);
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A , 0xFABA);
|
|
RR32( devAddr, SIO_TOP_JTAGID_LO__A , &jtag );
|
|
RR16( devAddr, SIO_PDR_UIO_IN_HI__A , &bid);
|
|
WR16( devAddr, SIO_TOP_COMM_KEY__A , key);
|
|
|
|
extAttr->vVersion[1].moduleType = DRX_MODULE_DEVICE;
|
|
extAttr->vVersion[1].moduleName = deviceName;
|
|
extAttr->vVersion[1].vString = extAttr->vText[1];
|
|
extAttr->vVersion[1].vString[0] = 'D';
|
|
extAttr->vVersion[1].vString[1] = 'R';
|
|
extAttr->vVersion[1].vString[2] = 'X';
|
|
extAttr->vVersion[1].vString[3] = '3';
|
|
extAttr->vVersion[1].vString[4] = '9';
|
|
extAttr->vVersion[1].vString[7] = 'J';
|
|
extAttr->vVersion[1].vString[8] = ':';
|
|
extAttr->vVersion[1].vString[11] = '\0';
|
|
|
|
/* DRX39xxJ type Ax */
|
|
/* TODO semantics of mfx and spin are unclear */
|
|
subtype = (u16_t)((jtag>>12)&0xFF);
|
|
mfx = (u16_t)(jtag>>29);
|
|
extAttr->vVersion[1].vMinor = 1;
|
|
if (mfx == 0x03)
|
|
{
|
|
extAttr->vVersion[1].vPatch = mfx+2;
|
|
}
|
|
else
|
|
{
|
|
extAttr->vVersion[1].vPatch = mfx+1;
|
|
}
|
|
extAttr->vVersion[1].vString[6] = ((char)(subtype&0xF))+'0';
|
|
extAttr->vVersion[1].vMajor = (subtype & 0x0F);
|
|
subtype>>=4;
|
|
extAttr->vVersion[1].vString[5] = ((char)(subtype&0xF))+'0';
|
|
extAttr->vVersion[1].vMajor += 10*subtype;
|
|
extAttr->vVersion[1].vString[9] = 'A';
|
|
if (mfx == 0x03)
|
|
{
|
|
extAttr->vVersion[1].vString[10] = ((char)(mfx&0xF)) + '2' ;
|
|
}
|
|
else
|
|
{
|
|
extAttr->vVersion[1].vString[10] = ((char)(mfx&0xF)) + '1' ;
|
|
}
|
|
|
|
extAttr->vListElements[1].version = &(extAttr->vVersion[1]);
|
|
extAttr->vListElements[1].next = (pDRXVersionList_t)(NULL);
|
|
|
|
*versionList = &(extAttr->vListElements[0]);
|
|
|
|
return ( DRX_STS_OK );
|
|
|
|
rw_error:
|
|
*versionList = (pDRXVersionList_t)(NULL);
|
|
return (DRX_STS_ERROR);
|
|
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlProbeDevice()
|
|
* \brief Probe device, check if it is present
|
|
* \param demod Pointer to demodulator instance.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK a drx39xxj device has been detected.
|
|
* \retval DRX_STS_ERROR no drx39xxj device detected.
|
|
*
|
|
* This funtion can be caled before open() and after close().
|
|
*
|
|
*/
|
|
|
|
static DRXStatus_t
|
|
CtrlProbeDevice( pDRXDemodInstance_t demod )
|
|
{
|
|
DRXPowerMode_t orgPowerMode = DRX_POWER_UP;
|
|
DRXStatus_t retStatus = DRX_STS_OK;
|
|
pDRXCommonAttr_t commonAttr = (pDRXCommonAttr_t)(NULL);
|
|
|
|
commonAttr = (pDRXCommonAttr_t)demod -> myCommonAttr;
|
|
|
|
if ( commonAttr->isOpened == FALSE || commonAttr->currentPowerMode != DRX_POWER_UP)
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXPowerMode_t powerMode = DRX_POWER_UP;
|
|
u32_t jtag = 0;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* Remeber original power mode */
|
|
orgPowerMode = commonAttr->currentPowerMode;
|
|
|
|
if(demod->myCommonAttr->isOpened == FALSE)
|
|
{
|
|
CHK_ERROR(PowerUpDevice(demod));
|
|
commonAttr->currentPowerMode = DRX_POWER_UP;
|
|
}
|
|
else
|
|
{
|
|
/* Wake-up device, feedback from device */
|
|
CHK_ERROR( CtrlPowerMode( demod, &powerMode ));
|
|
}
|
|
/* Initialize HI, wakeup key especially */
|
|
CHK_ERROR(InitHI(demod) );
|
|
|
|
/* Check device id */
|
|
RR32( devAddr, SIO_TOP_JTAGID_LO__A , &jtag);
|
|
jtag = (jtag>>12) & 0xFFFF;
|
|
switch ( jtag )
|
|
{
|
|
case 0x3931: /* fallthrough */
|
|
case 0x3932: /* fallthrough */
|
|
case 0x3933: /* fallthrough */
|
|
case 0x3934: /* fallthrough */
|
|
case 0x3941: /* fallthrough */
|
|
case 0x3942: /* fallthrough */
|
|
case 0x3943: /* fallthrough */
|
|
case 0x3944: /* fallthrough */
|
|
case 0x3945: /* fallthrough */
|
|
case 0x3946:
|
|
/* ok , do nothing */
|
|
break;
|
|
default:
|
|
retStatus = DRX_STS_ERROR;
|
|
break;
|
|
}
|
|
|
|
/* Device was not opened, return to orginal powermode,
|
|
feedback from device */
|
|
CHK_ERROR( CtrlPowerMode( demod, &orgPowerMode ));
|
|
}
|
|
else
|
|
{
|
|
/* dummy read to make this function fail in case device
|
|
suddenly disappears after a succesful DRX_Open */
|
|
DUMMY_READ();
|
|
}
|
|
|
|
return ( retStatus );
|
|
|
|
rw_error:
|
|
commonAttr->currentPowerMode=orgPowerMode;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t IsMCBlockAudio()
|
|
* \brief Check if MC block is Audio or not Audio.
|
|
* \param addr Pointer to demodulator instance.
|
|
* \param audioUpload TRUE if MC block is Audio
|
|
FALSE if MC block not Audio
|
|
* \return Bool_t.
|
|
*/
|
|
Bool_t IsMCBlockAudio( u32_t addr )
|
|
{
|
|
if ( ( addr == AUD_XFP_PRAM_4K__A ) ||
|
|
( addr == AUD_XDFP_PRAM_4K__A ) )
|
|
{
|
|
return ( TRUE );
|
|
}
|
|
return ( FALSE );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlUCodeUpload()
|
|
* \brief Handle Audio or !Audio part of microcode upload.
|
|
* \param demod Pointer to demodulator instance.
|
|
* \param mcInfo Pointer to information about microcode data.
|
|
* \param action Either UCODE_UPLOAD or UCODE_VERIFY.
|
|
* \param uploadAudioMC TRUE if Audio MC need to be uploaded.
|
|
FALSE if !Audio MC need to be uploaded.
|
|
* \return DRXStatus_t.
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlUCodeUpload( pDRXDemodInstance_t demod,
|
|
pDRXUCodeInfo_t mcInfo,
|
|
DRXUCodeAction_t action,
|
|
Bool_t uploadAudioMC )
|
|
{
|
|
u16_t i = 0;
|
|
u16_t mcNrOfBlks = 0;
|
|
u16_t mcMagicWord = 0;
|
|
pu8_t mcData = (pu8_t)(NULL);
|
|
pI2CDeviceAddr_t devAddr = (pI2CDeviceAddr_t)(NULL);
|
|
pDRXJData_t extAttr = (pDRXJData_t)(NULL);
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod -> myExtAttr;
|
|
|
|
/* Check arguments */
|
|
if ( ( mcInfo == NULL ) ||
|
|
( mcInfo->mcData == NULL ) ||
|
|
( mcInfo->mcSize == 0 ) )
|
|
{
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
mcData = mcInfo->mcData;
|
|
|
|
/* Check data */
|
|
mcMagicWord = UCodeRead16( mcData );
|
|
mcData += sizeof( u16_t );
|
|
mcNrOfBlks = UCodeRead16( mcData );
|
|
mcData += sizeof( u16_t );
|
|
|
|
if ( ( mcMagicWord != DRXJ_UCODE_MAGIC_WORD ) ||
|
|
( mcNrOfBlks == 0 ) )
|
|
{
|
|
/* wrong endianess or wrong data ? */
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
/* Process microcode blocks */
|
|
for( i = 0 ; i<mcNrOfBlks ; i++ )
|
|
{
|
|
DRXUCodeBlockHdr_t blockHdr;
|
|
u16_t mcBlockNrBytes = 0;
|
|
|
|
/* Process block header */
|
|
blockHdr.addr = UCodeRead32( mcData );
|
|
mcData += sizeof(u32_t);
|
|
blockHdr.size = UCodeRead16( mcData );
|
|
mcData += sizeof(u16_t);
|
|
blockHdr.flags = UCodeRead16( mcData );
|
|
mcData += sizeof(u16_t);
|
|
blockHdr.CRC = UCodeRead16( mcData );
|
|
mcData += sizeof(u16_t);
|
|
|
|
/* Check block header on:
|
|
- no data
|
|
- data larger then 64Kb
|
|
- if CRC enabled check CRC
|
|
*/
|
|
if ( ( blockHdr.size == 0 ) ||
|
|
( blockHdr.size > 0x7FFF ) ||
|
|
( (( blockHdr.flags & DRXJ_UCODE_CRC_FLAG ) != 0) &&
|
|
( blockHdr.CRC != UCodeComputeCRC( mcData, blockHdr.size)) )
|
|
)
|
|
{
|
|
/* Wrong data ! */
|
|
return DRX_STS_INVALID_ARG;
|
|
}
|
|
|
|
mcBlockNrBytes = blockHdr.size * sizeof(u16_t);
|
|
|
|
/* Perform the desired action */
|
|
/* Check which part of MC need to be uploaded - Audio or not Audio */
|
|
if( IsMCBlockAudio( blockHdr.addr ) == uploadAudioMC )
|
|
{
|
|
switch ( action ) {
|
|
/*===================================================================*/
|
|
case UCODE_UPLOAD :
|
|
{
|
|
/* Upload microcode */
|
|
if ( demod->myAccessFunct->writeBlockFunc(
|
|
devAddr,
|
|
(DRXaddr_t) blockHdr.addr,
|
|
mcBlockNrBytes,
|
|
mcData,
|
|
0x0000) != DRX_STS_OK)
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
};
|
|
break;
|
|
|
|
/*===================================================================*/
|
|
case UCODE_VERIFY :
|
|
{
|
|
int result = 0;
|
|
u8_t mcDataBuffer[DRXJ_UCODE_MAX_BUF_SIZE];
|
|
u32_t bytesToCompare=0;
|
|
u32_t bytesLeftToCompare=0;
|
|
DRXaddr_t currAddr = (DRXaddr_t)0;
|
|
pu8_t currPtr =NULL;
|
|
|
|
bytesLeftToCompare = mcBlockNrBytes;
|
|
currAddr = blockHdr.addr;
|
|
currPtr = mcData;
|
|
|
|
while( bytesLeftToCompare != 0 )
|
|
{
|
|
if (bytesLeftToCompare > ((u32_t)DRXJ_UCODE_MAX_BUF_SIZE) )
|
|
{
|
|
bytesToCompare = ((u32_t)DRXJ_UCODE_MAX_BUF_SIZE);
|
|
} else {
|
|
bytesToCompare = bytesLeftToCompare;
|
|
}
|
|
|
|
if ( demod->myAccessFunct->readBlockFunc(
|
|
devAddr,
|
|
currAddr,
|
|
(u16_t)bytesToCompare,
|
|
(pu8_t)mcDataBuffer,
|
|
0x0000) != DRX_STS_OK)
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
result = DRXBSP_HST_Memcmp( currPtr,
|
|
mcDataBuffer,
|
|
bytesToCompare);
|
|
|
|
if ( result != 0 )
|
|
{
|
|
return (DRX_STS_ERROR);
|
|
};
|
|
|
|
currAddr += ((DRXaddr_t)(bytesToCompare/2));
|
|
currPtr = &(currPtr[bytesToCompare]);
|
|
bytesLeftToCompare -= ((u32_t)bytesToCompare);
|
|
} /* while( bytesToCompare > DRXJ_UCODE_MAX_BUF_SIZE ) */
|
|
};
|
|
break;
|
|
|
|
/*===================================================================*/
|
|
default:
|
|
return DRX_STS_INVALID_ARG;
|
|
break;
|
|
|
|
} /* switch ( action ) */
|
|
} /* if( IsMCBlockAudio( blockHdr.addr ) == uploadAudioMC ) */
|
|
|
|
/* Next block */
|
|
mcData += mcBlockNrBytes;
|
|
} /* for( i = 0 ; i<mcNrOfBlks ; i++ ) */
|
|
|
|
if ( uploadAudioMC == FALSE )
|
|
{
|
|
extAttr->flagAudMcUploaded = FALSE;
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
}
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
|
|
/*============================================================================*/
|
|
/*== CTRL Set/Get Config related functions ===================================*/
|
|
/*============================================================================*/
|
|
|
|
/*===== SigStrength() =========================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlSigStrength()
|
|
* \brief Retrieve signal strength.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param sigQuality Pointer to signal strength data; range 0, .. , 100.
|
|
* \return DRXStatus_t.
|
|
* \retval DRX_STS_OK sigStrength contains valid data.
|
|
* \retval DRX_STS_INVALID_ARG sigStrength is NULL.
|
|
* \retval DRX_STS_ERROR Erroneous data, sigStrength contains invalid data.
|
|
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSigStrength( pDRXDemodInstance_t demod,
|
|
pu16_t sigStrength )
|
|
{
|
|
pDRXJData_t extAttr = NULL;
|
|
DRXStandard_t standard = DRX_STANDARD_UNKNOWN;
|
|
|
|
/* Check arguments */
|
|
if ( ( sigStrength == NULL ) ||
|
|
( demod == NULL ) )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
standard = extAttr->standard;
|
|
*sigStrength = 0;
|
|
|
|
/* Signal strength indication for each standard */
|
|
switch ( standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
CHK_ERROR( GetSigStrength( demod, sigStrength ) );
|
|
break;
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
CHK_ERROR( GetAtvSigStrength( demod, sigStrength ) );
|
|
break;
|
|
#endif
|
|
case DRX_STANDARD_UNKNOWN: /* fallthrough */
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* TODO */
|
|
/* find out if signal strength is calculated in the same way for all standards */
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgOOBMisc()
|
|
* \brief Get current state information of OOB.
|
|
* \param pointer to DRXJCfgOOBMisc_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
static DRXStatus_t
|
|
CtrlGetCfgOOBMisc ( pDRXDemodInstance_t demod, pDRXJCfgOOBMisc_t misc )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
u16_t lock = 0U;
|
|
u16_t state = 0U;
|
|
u16_t data = 0U;
|
|
u16_t digitalAGCMant = 0U;
|
|
u16_t digitalAGCExp = 0U;
|
|
|
|
/* check arguments */
|
|
if ( misc == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
/* TODO */
|
|
/* check if the same registers are used for all standards (QAM/VSB/ATV) */
|
|
RR16( devAddr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC );
|
|
RR16( devAddr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC );
|
|
RR16( devAddr, ORX_FWP_SRC_DGN_W__A, &data );
|
|
|
|
digitalAGCMant = data & ORX_FWP_SRC_DGN_W_MANT__M;
|
|
digitalAGCExp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
|
|
>> ORX_FWP_SRC_DGN_W_EXP__B;
|
|
misc->agc.DigitalAGC = digitalAGCMant << digitalAGCExp;
|
|
|
|
SARR16( devAddr, SCU_RAM_ORX_SCU_LOCK__A, &lock );
|
|
|
|
misc->anaGainLock = ((lock & 0x0001)?TRUE:FALSE);
|
|
misc->digGainLock = ((lock & 0x0002)?TRUE:FALSE);
|
|
misc->freqLock = ((lock & 0x0004)?TRUE:FALSE);
|
|
misc->phaseLock = ((lock & 0x0008)?TRUE:FALSE);
|
|
misc->symTimingLock = ((lock & 0x0010)?TRUE:FALSE);
|
|
misc->eqLock = ((lock & 0x0020)?TRUE:FALSE);
|
|
|
|
SARR16( devAddr, SCU_RAM_ORX_SCU_STATE__A, &state );
|
|
misc->state = (state>>8) & 0xff;
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgVSBMisc()
|
|
* \brief Get current state information of OOB.
|
|
* \param pointer to DRXJCfgOOBMisc_t.
|
|
* \return DRXStatus_t.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgVSBMisc ( pDRXDemodInstance_t demod, pDRXJCfgVSBMisc_t misc )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
|
|
/* check arguments */
|
|
if ( misc == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
devAddr = demod -> myI2CDevAddr;
|
|
|
|
CHK_ERROR(GetVSBSymbErr(devAddr, &misc->symbError));
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgAgcIf()
|
|
* \brief Set IF AGC.
|
|
* \param demod demod instance
|
|
* \param agcSettings If agc configuration
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgAgcIf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
/* check arguments */
|
|
if ( agcSettings == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
switch ( agcSettings->ctrlMode ) {
|
|
case DRX_AGC_CTRL_AUTO: /* fallthrough */
|
|
case DRX_AGC_CTRL_USER: /* fallthrough */
|
|
case DRX_AGC_CTRL_OFF: /* fallthrough */
|
|
break;
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* Distpatch */
|
|
switch ( agcSettings->standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
#endif
|
|
return SetAgcIf ( demod, agcSettings, TRUE);
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAgcIf()
|
|
* \brief Retrieve IF AGC settings.
|
|
* \param demod demod instance
|
|
* \param agcSettings If agc configuration
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAgcIf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
/* check arguments */
|
|
if ( agcSettings == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* Distpatch */
|
|
switch ( agcSettings->standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
#endif
|
|
return GetAgcIf ( demod, agcSettings);
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgAgcRf()
|
|
* \brief Set RF AGC.
|
|
* \param demod demod instance
|
|
* \param agcSettings rf agc configuration
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgAgcRf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
/* check arguments */
|
|
if ( agcSettings == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
switch ( agcSettings->ctrlMode ) {
|
|
case DRX_AGC_CTRL_AUTO: /* fallthrough */
|
|
case DRX_AGC_CTRL_USER: /* fallthrough */
|
|
case DRX_AGC_CTRL_OFF:
|
|
break;
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* Distpatch */
|
|
switch ( agcSettings->standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
#endif
|
|
return SetAgcRf ( demod, agcSettings, TRUE);
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAgcRf()
|
|
* \brief Retrieve RF AGC settings.
|
|
* \param demod demod instance
|
|
* \param agcSettings Rf agc configuration
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAgcRf ( pDRXDemodInstance_t demod, pDRXJCfgAgc_t agcSettings )
|
|
{
|
|
/* check arguments */
|
|
if ( agcSettings == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* Distpatch */
|
|
switch ( agcSettings->standard ) {
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
#endif
|
|
return GetAgcRf ( demod, agcSettings);
|
|
case DRX_STANDARD_UNKNOWN:
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAgcInternal()
|
|
* \brief Retrieve internal AGC value.
|
|
* \param demod demod instance
|
|
* \param u16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAgcInternal ( pDRXDemodInstance_t demod, pu16_t agcInternal )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
DRXLockStatus_t lockStatus = DRX_NOT_LOCKED;
|
|
pDRXJData_t extAttr = NULL;
|
|
u16_t iqmCfScaleSh = 0;
|
|
u16_t iqmCfPower = 0;
|
|
u16_t iqmCfAmp = 0;
|
|
u16_t iqmCfGain = 0;
|
|
|
|
/* check arguments */
|
|
if ( agcInternal == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
CHK_ERROR( CtrlLockStatus( demod, &lockStatus) );
|
|
if ( lockStatus != DRXJ_DEMOD_LOCK && lockStatus != DRX_LOCKED )
|
|
{
|
|
*agcInternal = 0;
|
|
return DRX_STS_OK;
|
|
}
|
|
|
|
/* Distpatch */
|
|
switch ( extAttr->standard ) {
|
|
case DRX_STANDARD_8VSB:
|
|
iqmCfGain = 57;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A:
|
|
case DRX_STANDARD_ITU_B:
|
|
case DRX_STANDARD_ITU_C:
|
|
switch ( extAttr->constellation )
|
|
{
|
|
case DRX_CONSTELLATION_QAM256:
|
|
case DRX_CONSTELLATION_QAM128:
|
|
case DRX_CONSTELLATION_QAM32:
|
|
case DRX_CONSTELLATION_QAM16:
|
|
iqmCfGain = 57;
|
|
break;
|
|
case DRX_CONSTELLATION_QAM64:
|
|
iqmCfGain = 56;
|
|
break;
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
break;
|
|
#endif
|
|
default:
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
RR16( devAddr, IQM_CF_POW__A, &iqmCfPower);
|
|
RR16( devAddr, IQM_CF_SCALE_SH__A, &iqmCfScaleSh);
|
|
RR16( devAddr, IQM_CF_AMP__A, &iqmCfAmp);
|
|
/* IQM_CF_PWR_CORRECTION_dB = 3;
|
|
P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
|
|
/* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
|
|
-IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
|
|
+6*7+10*log10(1+0.115/4); */
|
|
/* PadcdB = P4dB +3 -6 +60; dBmV */
|
|
*agcInternal = (u16_t) ( Log10Times100 (iqmCfPower)
|
|
- 2 * Log10Times100 (iqmCfAmp)
|
|
- iqmCfGain
|
|
- 120 * iqmCfScaleSh
|
|
+ 781 );
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgPreSaw()
|
|
* \brief Set Pre-saw reference.
|
|
* \param demod demod instance
|
|
* \param pu16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgPreSaw ( pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
/* check arguments */
|
|
if ( ( preSaw == NULL ) ||
|
|
( preSaw->reference > IQM_AF_PDREF__M )
|
|
)
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
/* Only if standard is currently active*/
|
|
if ( ( extAttr->standard == preSaw->standard ) ||
|
|
( DRXJ_ISQAMSTD( extAttr->standard ) &&
|
|
DRXJ_ISQAMSTD( preSaw->standard ) ) ||
|
|
( DRXJ_ISATVSTD( extAttr->standard ) &&
|
|
DRXJ_ISATVSTD( preSaw->standard ) ) )
|
|
{
|
|
WR16( devAddr, IQM_AF_PDREF__A , preSaw->reference);
|
|
}
|
|
|
|
/* Store pre-saw settings */
|
|
switch ( preSaw->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
extAttr->vsbPreSawCfg = *preSaw;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
extAttr->qamPreSawCfg = *preSaw;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC: /* fallthrough */
|
|
case DRX_STANDARD_FM:
|
|
extAttr->atvPreSawCfg = *preSaw;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfgAfeGain()
|
|
* \brief Set AFE Gain.
|
|
* \param demod demod instance
|
|
* \param pu16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfgAfeGain ( pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
u8_t gain = 0;
|
|
|
|
/* check arguments */
|
|
if ( afeGain == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
switch ( afeGain->standard){
|
|
case DRX_STANDARD_8VSB: /* fallthrough */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
#endif
|
|
/* Do nothing */
|
|
break;
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
/* TODO PGA gain is also written by microcode (at least by QAM and VSB)
|
|
So I (PJ) think interface requires choice between auto, user mode */
|
|
|
|
if (afeGain->gain >= 329)
|
|
gain = 15;
|
|
else if (afeGain->gain <= 147)
|
|
gain = 0;
|
|
else
|
|
gain = (afeGain->gain - 140 + 6) / 13;
|
|
|
|
/* Only if standard is currently active*/
|
|
if( extAttr->standard == afeGain->standard )
|
|
WR16( devAddr, IQM_AF_PGA_GAIN__A, gain);
|
|
|
|
/* Store AFE Gain settings */
|
|
switch ( afeGain->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
extAttr->vsbPgaCfg = gain * 13 + 140;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
extAttr->qamPgaCfg = gain * 13 + 140;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgPreSaw()
|
|
* \brief Get Pre-saw reference setting.
|
|
* \param demod demod instance
|
|
* \param pu16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgPreSaw ( pDRXDemodInstance_t demod, pDRXJCfgPreSaw_t preSaw )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* check arguments */
|
|
if ( preSaw == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
switch ( preSaw->standard ){
|
|
case DRX_STANDARD_8VSB:
|
|
*preSaw = extAttr->vsbPreSawCfg;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
*preSaw = extAttr->qamPreSawCfg;
|
|
break;
|
|
#endif
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRX_STANDARD_PAL_SECAM_BG : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_DK : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_I : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_L : /* fallthrough */
|
|
case DRX_STANDARD_PAL_SECAM_LP : /* fallthrough */
|
|
case DRX_STANDARD_NTSC:
|
|
extAttr->atvPreSawCfg.standard = DRX_STANDARD_NTSC;
|
|
*preSaw = extAttr->atvPreSawCfg;
|
|
break;
|
|
case DRX_STANDARD_FM:
|
|
extAttr->atvPreSawCfg.standard = DRX_STANDARD_FM;
|
|
*preSaw = extAttr->atvPreSawCfg;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfgAfeGain()
|
|
* \brief Get AFE Gain.
|
|
* \param demod demod instance
|
|
* \param pu16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetCfgAfeGain ( pDRXDemodInstance_t demod, pDRXJCfgAfeGain_t afeGain )
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
|
|
/* check arguments */
|
|
if ( afeGain == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t)demod->myExtAttr;
|
|
|
|
switch ( afeGain->standard){
|
|
case DRX_STANDARD_8VSB:
|
|
afeGain->gain = extAttr->vsbPgaCfg;
|
|
break;
|
|
#ifndef DRXJ_VSB_ONLY
|
|
case DRX_STANDARD_ITU_A: /* fallthrough */
|
|
case DRX_STANDARD_ITU_B: /* fallthrough */
|
|
case DRX_STANDARD_ITU_C:
|
|
afeGain->gain = extAttr->qamPgaCfg;
|
|
break;
|
|
#endif
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return ( DRX_STS_OK );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetFecMeasSeqCount()
|
|
* \brief Get FEC measurement sequnce number.
|
|
* \param demod demod instance
|
|
* \param pu16_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetFecMeasSeqCount ( pDRXDemodInstance_t demod, pu16_t fecMeasSeqCount)
|
|
{
|
|
/* check arguments */
|
|
if ( fecMeasSeqCount == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG );
|
|
}
|
|
|
|
RR16 ( demod->myI2CDevAddr, SCU_RAM_FEC_MEAS_COUNT__A, fecMeasSeqCount );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetAccumCrRSCwErr()
|
|
* \brief Get accumulative corrected RS codeword number.
|
|
* \param demod demod instance
|
|
* \param pu32_t
|
|
* \return DRXStatus_t.
|
|
*
|
|
* Check arguments
|
|
* Dispatch handling to standard specific function.
|
|
*
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlGetAccumCrRSCwErr ( pDRXDemodInstance_t demod, pu32_t accumCrRsCWErr)
|
|
{
|
|
if(accumCrRsCWErr == NULL)
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
RR32 ( demod->myI2CDevAddr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accumCrRsCWErr );
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlSetCfg()
|
|
* \brief Set 'some' configuration of the device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param config Pointer to configuration parameters (type and data).
|
|
* \return DRXStatus_t.
|
|
|
|
*/
|
|
static DRXStatus_t
|
|
CtrlSetCfg( pDRXDemodInstance_t demod,
|
|
pDRXCfg_t config )
|
|
{
|
|
if ( config == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
DUMMY_READ();
|
|
switch ( config->cfgType )
|
|
{
|
|
case DRX_CFG_MPEG_OUTPUT:
|
|
return CtrlSetCfgMPEGOutput( demod, (pDRXCfgMPEGOutput_t) config->cfgData );
|
|
case DRX_CFG_PINS_SAFE_MODE:
|
|
return CtrlSetCfgPdrSafeMode( demod, (pBool_t) config->cfgData );
|
|
case DRXJ_CFG_AGC_RF:
|
|
return CtrlSetCfgAgcRf ( demod, (pDRXJCfgAgc_t) config->cfgData );
|
|
case DRXJ_CFG_AGC_IF:
|
|
return CtrlSetCfgAgcIf ( demod, (pDRXJCfgAgc_t) config->cfgData );
|
|
case DRXJ_CFG_PRE_SAW:
|
|
return CtrlSetCfgPreSaw ( demod, (pDRXJCfgPreSaw_t) config->cfgData );
|
|
case DRXJ_CFG_AFE_GAIN:
|
|
return CtrlSetCfgAfeGain ( demod, (pDRXJCfgAfeGain_t) config->cfgData );
|
|
case DRXJ_CFG_SMART_ANT:
|
|
return CtrlSetCfgSmartAnt ( demod, (pDRXJCfgSmartAnt_t)(config->cfgData) );
|
|
case DRXJ_CFG_RESET_PACKET_ERR:
|
|
return CtrlSetCfgResetPktErr ( demod );
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRXJ_CFG_OOB_PRE_SAW:
|
|
return CtrlSetCfgOOBPreSAW ( demod, (pu16_t)(config->cfgData) );
|
|
case DRXJ_CFG_OOB_LO_POW:
|
|
return CtrlSetCfgOOBLoPower ( demod, (pDRXJCfgOobLoPower_t)(config->cfgData) );
|
|
case DRXJ_CFG_ATV_MISC:
|
|
return CtrlSetCfgAtvMisc( demod, (pDRXJCfgAtvMisc_t) config->cfgData );
|
|
case DRXJ_CFG_ATV_EQU_COEF:
|
|
return CtrlSetCfgAtvEquCoef( demod,
|
|
(pDRXJCfgAtvEquCoef_t) config->cfgData );
|
|
case DRXJ_CFG_ATV_OUTPUT:
|
|
return CtrlSetCfgATVOutput( demod,
|
|
(pDRXJCfgAtvOutput_t) config->cfgData );
|
|
#endif
|
|
case DRXJ_CFG_MPEG_OUTPUT_MISC:
|
|
return CtrlSetCfgMpegOutputMisc( demod,
|
|
(pDRXJCfgMpegOutputMisc_t) config->cfgData );
|
|
#ifndef DRXJ_EXCLUDE_AUDIO
|
|
case DRX_CFG_AUD_VOLUME:
|
|
return AUDCtrlSetCfgVolume( demod,
|
|
(pDRXCfgAudVolume_t)config->cfgData );
|
|
case DRX_CFG_I2S_OUTPUT:
|
|
return AUDCtrlSetCfgOutputI2S( demod,
|
|
(pDRXCfgI2SOutput_t)config->cfgData );
|
|
case DRX_CFG_AUD_AUTOSOUND:
|
|
return AUDCtrSetlCfgAutoSound( demod,
|
|
(pDRXCfgAudAutoSound_t)
|
|
config->cfgData);
|
|
case DRX_CFG_AUD_ASS_THRES:
|
|
return AUDCtrlSetCfgASSThres( demod,
|
|
(pDRXCfgAudASSThres_t)
|
|
config->cfgData);
|
|
case DRX_CFG_AUD_CARRIER:
|
|
return AUDCtrlSetCfgCarrier( demod,
|
|
(pDRXCfgAudCarriers_t)config->cfgData);
|
|
case DRX_CFG_AUD_DEVIATION:
|
|
return AUDCtrlSetCfgDev( demod,
|
|
(pDRXCfgAudDeviation_t)config->cfgData);
|
|
case DRX_CFG_AUD_PRESCALE:
|
|
return AUDCtrlSetCfgPrescale( demod,
|
|
(pDRXCfgAudPrescale_t)config->cfgData);
|
|
case DRX_CFG_AUD_MIXER:
|
|
return AUDCtrlSetCfgMixer( demod,
|
|
(pDRXCfgAudMixer_t)config->cfgData);
|
|
case DRX_CFG_AUD_AVSYNC:
|
|
return AUDCtrlSetCfgAVSync( demod,
|
|
(pDRXCfgAudAVSync_t)config->cfgData);
|
|
|
|
#endif
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
/**
|
|
* \fn DRXStatus_t CtrlGetCfg()
|
|
* \brief Get 'some' configuration of the device.
|
|
* \param devmod Pointer to demodulator instance.
|
|
* \param config Pointer to configuration parameters (type and data).
|
|
* \return DRXStatus_t.
|
|
*/
|
|
|
|
static DRXStatus_t
|
|
CtrlGetCfg( pDRXDemodInstance_t demod,
|
|
pDRXCfg_t config )
|
|
{
|
|
if ( config == NULL )
|
|
{
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
DUMMY_READ();
|
|
|
|
switch ( config->cfgType )
|
|
{
|
|
case DRX_CFG_MPEG_OUTPUT:
|
|
return CtrlGetCfgMPEGOutput( demod,
|
|
(pDRXCfgMPEGOutput_t) config->cfgData );
|
|
case DRX_CFG_PINS_SAFE_MODE:
|
|
return CtrlGetCfgPdrSafeMode( demod, (pBool_t) config->cfgData );
|
|
case DRXJ_CFG_AGC_RF:
|
|
return CtrlGetCfgAgcRf ( demod, (pDRXJCfgAgc_t) config->cfgData );
|
|
case DRXJ_CFG_AGC_IF:
|
|
return CtrlGetCfgAgcIf ( demod, (pDRXJCfgAgc_t) config->cfgData );
|
|
case DRXJ_CFG_AGC_INTERNAL:
|
|
return CtrlGetCfgAgcInternal ( demod, (pu16_t) config->cfgData );
|
|
case DRXJ_CFG_PRE_SAW:
|
|
return CtrlGetCfgPreSaw ( demod, (pDRXJCfgPreSaw_t) config->cfgData );
|
|
case DRXJ_CFG_AFE_GAIN:
|
|
return CtrlGetCfgAfeGain ( demod, (pDRXJCfgAfeGain_t) config->cfgData );
|
|
case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
|
|
return CtrlGetAccumCrRSCwErr ( demod, (pu32_t) config->cfgData );
|
|
case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
|
|
return CtrlGetFecMeasSeqCount ( demod, (pu16_t) config->cfgData );
|
|
case DRXJ_CFG_VSB_MISC:
|
|
return CtrlGetCfgVSBMisc ( demod, (pDRXJCfgVSBMisc_t) config->cfgData );
|
|
case DRXJ_CFG_SYMBOL_CLK_OFFSET:
|
|
return CtrlGetCfgSymbolClockOffset ( demod, (ps32_t) config->cfgData );
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
case DRXJ_CFG_OOB_MISC:
|
|
return CtrlGetCfgOOBMisc ( demod, (pDRXJCfgOOBMisc_t) config->cfgData );
|
|
case DRXJ_CFG_OOB_PRE_SAW:
|
|
return CtrlGetCfgOOBPreSAW ( demod, (pu16_t)(config->cfgData) );
|
|
case DRXJ_CFG_OOB_LO_POW:
|
|
return CtrlGetCfgOOBLoPower ( demod, (pDRXJCfgOobLoPower_t)(config->cfgData) );
|
|
case DRXJ_CFG_ATV_EQU_COEF:
|
|
return CtrlGetCfgAtvEquCoef( demod,
|
|
(pDRXJCfgAtvEquCoef_t) config->cfgData );
|
|
case DRXJ_CFG_ATV_MISC:
|
|
return CtrlGetCfgAtvMisc( demod, (pDRXJCfgAtvMisc_t) config->cfgData );
|
|
case DRXJ_CFG_ATV_OUTPUT:
|
|
return CtrlGetCfgAtvOutput( demod,
|
|
(pDRXJCfgAtvOutput_t) config->cfgData );
|
|
case DRXJ_CFG_ATV_AGC_STATUS:
|
|
return CtrlGetCfgAtvAgcStatus( demod,
|
|
(pDRXJCfgAtvAgcStatus_t) config->cfgData );
|
|
#endif
|
|
case DRXJ_CFG_MPEG_OUTPUT_MISC:
|
|
return CtrlGetCfgMpegOutputMisc( demod,
|
|
(pDRXJCfgMpegOutputMisc_t) config->cfgData );
|
|
case DRXJ_CFG_HW_CFG:
|
|
return CtrlGetCfgHwCfg( demod,
|
|
(pDRXJCfgHwCfg_t) config->cfgData );
|
|
#ifndef DRXJ_EXCLUDE_AUDIO
|
|
case DRX_CFG_AUD_VOLUME:
|
|
return AUDCtrlGetCfgVolume ( demod,
|
|
(pDRXCfgAudVolume_t)config->cfgData );
|
|
case DRX_CFG_I2S_OUTPUT:
|
|
return AUDCtrlGetCfgOutputI2S ( demod,
|
|
(pDRXCfgI2SOutput_t)config->cfgData );
|
|
|
|
case DRX_CFG_AUD_RDS:
|
|
return AUDCtrlGetCfgRDS ( demod,
|
|
(pDRXCfgAudRDS_t)config->cfgData );
|
|
case DRX_CFG_AUD_AUTOSOUND:
|
|
return AUDCtrlGetCfgAutoSound ( demod,
|
|
(pDRXCfgAudAutoSound_t)config->cfgData);
|
|
case DRX_CFG_AUD_ASS_THRES:
|
|
return AUDCtrlGetCfgASSThres ( demod,
|
|
(pDRXCfgAudASSThres_t)config->cfgData);
|
|
case DRX_CFG_AUD_CARRIER:
|
|
return AUDCtrlGetCfgCarrier ( demod,
|
|
(pDRXCfgAudCarriers_t)config->cfgData);
|
|
case DRX_CFG_AUD_DEVIATION:
|
|
return AUDCtrlGetCfgDev ( demod,
|
|
(pDRXCfgAudDeviation_t)config->cfgData);
|
|
case DRX_CFG_AUD_PRESCALE:
|
|
return AUDCtrlGetCfgPrescale ( demod,
|
|
(pDRXCfgAudPrescale_t)config->cfgData);
|
|
case DRX_CFG_AUD_MIXER:
|
|
return AUDCtrlGetCfgMixer ( demod,
|
|
(pDRXCfgAudMixer_t)config->cfgData);
|
|
case DRX_CFG_AUD_AVSYNC:
|
|
return AUDCtrlGetCfgAVSync ( demod,
|
|
(pDRXCfgAudAVSync_t)config->cfgData);
|
|
#endif
|
|
|
|
default:
|
|
return (DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
return (DRX_STS_OK);
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*=============================================================================
|
|
===== EXPORTED FUNCTIONS ====================================================*/
|
|
/**
|
|
* \fn DRXJ_Open()
|
|
* \brief Open the demod instance, configure device, configure drxdriver
|
|
* \return Status_t Return status.
|
|
*
|
|
* DRXJ_Open() can be called with a NULL ucode image => no ucode upload.
|
|
* This means that DRXJ_Open() must NOT contain SCU commands or, in general,
|
|
* rely on SCU or AUD ucode to be present.
|
|
*
|
|
*/
|
|
DRXStatus_t
|
|
DRXJ_Open(pDRXDemodInstance_t demod)
|
|
{
|
|
pI2CDeviceAddr_t devAddr = NULL;
|
|
pDRXJData_t extAttr = NULL;
|
|
pDRXCommonAttr_t commonAttr = NULL;
|
|
u32_t driverVersion = 0;
|
|
DRXUCodeInfo_t ucodeInfo;
|
|
DRXCfgMPEGOutput_t cfgMPEGOutput;
|
|
|
|
/* Check arguments */
|
|
if (demod -> myExtAttr == NULL )
|
|
{
|
|
return ( DRX_STS_INVALID_ARG);
|
|
}
|
|
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
|
|
CHK_ERROR(PowerUpDevice(demod));
|
|
commonAttr->currentPowerMode = DRX_POWER_UP;
|
|
|
|
/* has to be in front of setIqmAf and setOrxNsuAox */
|
|
CHK_ERROR(GetDeviceCapabilities(demod));
|
|
|
|
/* Soft reset of sys- and osc-clockdomain */
|
|
WR16( devAddr, SIO_CC_SOFT_RST__A, ( SIO_CC_SOFT_RST_SYS__M |
|
|
SIO_CC_SOFT_RST_OSC__M ) );
|
|
WR16( devAddr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
|
|
CHK_ERROR( DRXBSP_HST_Sleep(1) );
|
|
|
|
/* TODO first make sure that everything keeps working before enabling this */
|
|
/* PowerDownAnalogBlocks() */
|
|
WR16( devAddr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
|
|
|ATV_TOP_STDBY_SIF_STDBY_STANDBY );
|
|
|
|
CHK_ERROR( SetIqmAf( demod, FALSE ) );
|
|
CHK_ERROR( SetOrxNsuAox( demod, FALSE ) );
|
|
|
|
CHK_ERROR(InitHI(demod) );
|
|
|
|
/* disable mpegoutput pins */
|
|
cfgMPEGOutput.enableMPEGOutput = FALSE;
|
|
CHK_ERROR( CtrlSetCfgMPEGOutput( demod, &cfgMPEGOutput) );
|
|
/* Stop AUD Inform SetAudio it will need to do all setting */
|
|
CHK_ERROR( PowerDownAud(demod) );
|
|
/* Stop SCU */
|
|
WR16( devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
|
|
|
|
/* Upload microcode */
|
|
if ( commonAttr->microcode != NULL )
|
|
{
|
|
/* Dirty trick to use common ucode upload & verify,
|
|
pretend device is already open */
|
|
commonAttr->isOpened = TRUE;
|
|
ucodeInfo.mcData = commonAttr->microcode;
|
|
ucodeInfo.mcSize = commonAttr->microcodeSize;
|
|
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
/* Upload microcode without audio part */
|
|
CHK_ERROR( CtrlUCodeUpload( demod, &ucodeInfo, UCODE_UPLOAD, FALSE ) );
|
|
#else
|
|
CHK_ERROR( DRX_Ctrl( demod, DRX_CTRL_LOAD_UCODE, &ucodeInfo) );
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
if ( commonAttr->verifyMicrocode == TRUE )
|
|
{
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
CHK_ERROR( CtrlUCodeUpload( demod, &ucodeInfo, UCODE_VERIFY, FALSE ) );
|
|
#else
|
|
CHK_ERROR( DRX_Ctrl ( demod, DRX_CTRL_VERIFY_UCODE, &ucodeInfo) );
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
}
|
|
commonAttr->isOpened = FALSE;
|
|
}
|
|
|
|
/* Run SCU for a little while to initialize microcode version numbers */
|
|
WR16( devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
|
|
|
|
/* Open tuner instance */
|
|
if ( demod->myTuner != NULL )
|
|
{
|
|
demod->myTuner->myCommonAttr->myUserData = (void *)demod;
|
|
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
Bool_t bridgeClosed = TRUE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
|
|
CHK_ERROR( DRXBSP_TUNER_Open( demod -> myTuner ) );
|
|
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
Bool_t bridgeClosed = FALSE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
commonAttr->tunerMinFreqRF = ((demod->myTuner)->myCommonAttr->minFreqRF);
|
|
commonAttr->tunerMaxFreqRF = ((demod->myTuner)->myCommonAttr->maxFreqRF);
|
|
}
|
|
|
|
/* Initialize scan timeout */
|
|
commonAttr -> scanDemodLockTimeout = DRXJ_SCAN_TIMEOUT;
|
|
commonAttr -> scanDesiredLock = DRX_LOCKED;
|
|
|
|
/* Initialize default AFE configuartion for QAM */
|
|
if (extAttr->hasLNA)
|
|
{
|
|
/* IF AGC off, PGA active */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
extAttr->qamIfAgcCfg.standard = DRX_STANDARD_ITU_B;
|
|
extAttr->qamIfAgcCfg.ctrlMode = DRX_AGC_CTRL_OFF;
|
|
extAttr->qamPgaCfg = 140+(11*13);
|
|
#endif
|
|
extAttr->vsbIfAgcCfg.standard = DRX_STANDARD_8VSB;
|
|
extAttr->vsbIfAgcCfg.ctrlMode = DRX_AGC_CTRL_OFF;
|
|
extAttr->vsbPgaCfg = 140+(11*13);
|
|
} else {
|
|
/* IF AGC on, PGA not active */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
extAttr->qamIfAgcCfg.standard = DRX_STANDARD_ITU_B;
|
|
extAttr->qamIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->qamIfAgcCfg.minOutputLevel = 0;
|
|
extAttr->qamIfAgcCfg.maxOutputLevel = 0x7FFF;
|
|
extAttr->qamIfAgcCfg.speed = 3;
|
|
extAttr->qamIfAgcCfg.top = 1297;
|
|
extAttr->qamPgaCfg = 140;
|
|
#endif
|
|
extAttr->vsbIfAgcCfg.standard = DRX_STANDARD_8VSB;
|
|
extAttr->vsbIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->vsbIfAgcCfg.minOutputLevel = 0;
|
|
extAttr->vsbIfAgcCfg.maxOutputLevel = 0x7FFF;
|
|
extAttr->vsbIfAgcCfg.speed = 3;
|
|
extAttr->vsbIfAgcCfg.top = 1024;
|
|
extAttr->vsbPgaCfg = 140;
|
|
}
|
|
/* TODO: remove minOutputLevel and maxOutputLevel for both QAM and VSB after */
|
|
/* mc has not used them */
|
|
#ifndef DRXJ_VSB_ONLY
|
|
extAttr->qamRfAgcCfg.standard = DRX_STANDARD_ITU_B;
|
|
extAttr->qamRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->qamRfAgcCfg.minOutputLevel = 0;
|
|
extAttr->qamRfAgcCfg.maxOutputLevel = 0x7FFF;
|
|
extAttr->qamRfAgcCfg.speed = 3;
|
|
extAttr->qamRfAgcCfg.top = 9500;
|
|
extAttr->qamRfAgcCfg.cutOffCurrent = 4000;
|
|
extAttr->qamPreSawCfg.standard = DRX_STANDARD_ITU_B;
|
|
extAttr->qamPreSawCfg.reference = 0x07;
|
|
extAttr->qamPreSawCfg.usePreSaw = TRUE;
|
|
#endif
|
|
/* Initialize default AFE configuartion for VSB */
|
|
extAttr->vsbRfAgcCfg.standard = DRX_STANDARD_8VSB;
|
|
extAttr->vsbRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->vsbRfAgcCfg.minOutputLevel = 0;
|
|
extAttr->vsbRfAgcCfg.maxOutputLevel = 0x7FFF;
|
|
extAttr->vsbRfAgcCfg.speed = 3;
|
|
extAttr->vsbRfAgcCfg.top = 9500;
|
|
extAttr->vsbRfAgcCfg.cutOffCurrent = 4000;
|
|
extAttr->vsbPreSawCfg.standard = DRX_STANDARD_8VSB;
|
|
extAttr->vsbPreSawCfg.reference = 0x07;
|
|
extAttr->vsbPreSawCfg.usePreSaw = TRUE;
|
|
|
|
#ifndef DRXJ_DIGITAL_ONLY
|
|
/* Initialize default AFE configuartion for ATV */
|
|
extAttr->atvRfAgcCfg.standard = DRX_STANDARD_NTSC;
|
|
extAttr->atvRfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->atvRfAgcCfg.top = 9500;
|
|
extAttr->atvRfAgcCfg.cutOffCurrent = 4000;
|
|
extAttr->atvRfAgcCfg.speed = 3;
|
|
extAttr->atvIfAgcCfg.standard = DRX_STANDARD_NTSC;
|
|
extAttr->atvIfAgcCfg.ctrlMode = DRX_AGC_CTRL_AUTO;
|
|
extAttr->atvIfAgcCfg.speed = 3;
|
|
extAttr->atvIfAgcCfg.top = 2400;
|
|
extAttr->atvPreSawCfg.reference = 0x0007;
|
|
extAttr->atvPreSawCfg.usePreSaw = TRUE;
|
|
extAttr->atvPreSawCfg.standard = DRX_STANDARD_NTSC;
|
|
#endif
|
|
extAttr->standard=DRX_STANDARD_UNKNOWN;
|
|
|
|
CHK_ERROR(SmartAntInit(demod));
|
|
|
|
/* Stamp driver version number in SCU data RAM in BCD code
|
|
Done to enable field application engineers to retreive drxdriver version
|
|
via I2C from SCU RAM
|
|
*/
|
|
driverVersion = (VERSION_MAJOR/100) % 10;
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_MAJOR/10) % 10;
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_MAJOR%10);
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_MINOR%10);
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_PATCH/1000) % 10;
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_PATCH/100) % 10;
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_PATCH/10) % 10;
|
|
driverVersion <<= 4;
|
|
driverVersion += (VERSION_PATCH%10);
|
|
WR16(devAddr, SCU_RAM_DRIVER_VER_HI__A, (u16_t)(driverVersion>>16) );
|
|
WR16(devAddr, SCU_RAM_DRIVER_VER_LO__A, (u16_t)(driverVersion&0xFFFF) );
|
|
|
|
/* refresh the audio data structure with default */
|
|
extAttr->audData = DRXJDefaultAudData_g;
|
|
|
|
return ( DRX_STS_OK );
|
|
rw_error:
|
|
commonAttr->isOpened = FALSE;
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXJ_Close()
|
|
* \brief Close the demod instance, power down the device
|
|
* \return Status_t Return status.
|
|
*
|
|
*/
|
|
DRXStatus_t
|
|
DRXJ_Close(pDRXDemodInstance_t demod)
|
|
{
|
|
pI2CDeviceAddr_t devAddr =NULL;
|
|
pDRXJData_t extAttr =NULL;
|
|
pDRXCommonAttr_t commonAttr =NULL;
|
|
DRXPowerMode_t powerMode =DRX_POWER_UP;
|
|
|
|
commonAttr = (pDRXCommonAttr_t) demod -> myCommonAttr;
|
|
devAddr = demod -> myI2CDevAddr;
|
|
extAttr = (pDRXJData_t) demod -> myExtAttr;
|
|
|
|
/* power up */
|
|
CHK_ERROR( CtrlPowerMode( demod, &powerMode ));
|
|
|
|
if ( demod->myTuner != NULL )
|
|
{
|
|
/* Check if bridge is used */
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
Bool_t bridgeClosed = TRUE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
CHK_ERROR( DRXBSP_TUNER_Close( demod -> myTuner ) );
|
|
if ( commonAttr->tunerPortNr == 1 )
|
|
{
|
|
Bool_t bridgeClosed = FALSE;
|
|
CHK_ERROR( CtrlI2CBridge( demod, &bridgeClosed ) );
|
|
}
|
|
};
|
|
|
|
WR16( devAddr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
|
|
powerMode =DRX_POWER_DOWN;
|
|
CHK_ERROR( CtrlPowerMode( demod, &powerMode ));
|
|
|
|
return DRX_STS_OK;
|
|
rw_error:
|
|
return (DRX_STS_ERROR);
|
|
}
|
|
|
|
/*============================================================================*/
|
|
/**
|
|
* \fn DRXJ_Ctrl()
|
|
* \brief DRXJ specific control function
|
|
* \return Status_t Return status.
|
|
*/
|
|
DRXStatus_t
|
|
DRXJ_Ctrl(pDRXDemodInstance_t demod, DRXCtrlIndex_t ctrl,
|
|
void *ctrlData)
|
|
{
|
|
switch ( ctrl ) {
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SET_CHANNEL:
|
|
{
|
|
return CtrlSetChannel ( demod,
|
|
(pDRXChannel_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_GET_CHANNEL:
|
|
{
|
|
return CtrlGetChannel ( demod,
|
|
(pDRXChannel_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SIG_QUALITY:
|
|
{
|
|
return CtrlSigQuality ( demod,
|
|
(pDRXSigQuality_t) ctrlData);
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SIG_STRENGTH:
|
|
{
|
|
return CtrlSigStrength ( demod,
|
|
(pu16_t) ctrlData);
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_CONSTEL:
|
|
{
|
|
return CtrlConstel ( demod,
|
|
(pDRXComplex_t) ctrlData);
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SET_CFG:
|
|
{
|
|
return CtrlSetCfg ( demod,
|
|
(pDRXCfg_t) ctrlData);
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_GET_CFG:
|
|
{
|
|
return CtrlGetCfg ( demod, (pDRXCfg_t) ctrlData);
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_I2C_BRIDGE:
|
|
{
|
|
return CtrlI2CBridge( demod, (pBool_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_LOCK_STATUS:
|
|
{
|
|
return CtrlLockStatus( demod, (pDRXLockStatus_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SET_STANDARD:
|
|
{
|
|
return CtrlSetStandard( demod, (pDRXStandard_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_GET_STANDARD:
|
|
{
|
|
return CtrlGetStandard( demod, (pDRXStandard_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_POWER_MODE:
|
|
{
|
|
return CtrlPowerMode( demod, (pDRXPowerMode_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_VERSION:
|
|
{
|
|
return CtrlVersion( demod, (pDRXVersionList_t *) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_PROBE_DEVICE:
|
|
{
|
|
return CtrlProbeDevice( demod );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SET_OOB:
|
|
{
|
|
return CtrlSetOOB( demod, (pDRXOOB_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_GET_OOB:
|
|
{
|
|
return CtrlGetOOB( demod, (pDRXOOBStatus_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_SET_UIO_CFG:
|
|
{
|
|
return CtrlSetUIOCfg( demod, (pDRXUIOCfg_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_GET_UIO_CFG:
|
|
{
|
|
return CtrlGetUIOCfg( demod, (pDRXUIOCfg_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_UIO_READ:
|
|
{
|
|
return CtrlUIORead( demod, (pDRXUIOData_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_UIO_WRITE:
|
|
{
|
|
return CtrlUIOWrite( demod, (pDRXUIOData_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_AUD_SET_STANDARD:
|
|
{
|
|
return AUDCtrlSetStandard( demod, (pDRXAudStandard_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_AUD_GET_STANDARD:
|
|
{
|
|
return AUDCtrlGetStandard( demod, (pDRXAudStandard_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_AUD_GET_STATUS:
|
|
{
|
|
return AUDCtrlGetStatus( demod, (pDRXAudStatus_t) ctrlData );
|
|
}
|
|
break;
|
|
/*======================================================================*/
|
|
case DRX_CTRL_AUD_BEEP:
|
|
{
|
|
return AUDCtrlBeep( demod, (pDRXAudBeep_t) ctrlData );
|
|
}
|
|
break;
|
|
|
|
/*======================================================================*/
|
|
case DRX_CTRL_I2C_READWRITE:
|
|
{
|
|
return CtrlI2CWriteRead( demod, (pDRXI2CData_t) ctrlData );
|
|
}
|
|
break;
|
|
#ifdef DRXJ_SPLIT_UCODE_UPLOAD
|
|
case DRX_CTRL_LOAD_UCODE:
|
|
{
|
|
return CtrlUCodeUpload( demod, (pDRXUCodeInfo_t) ctrlData, UCODE_UPLOAD, FALSE );
|
|
}
|
|
break;
|
|
case DRX_CTRL_VERIFY_UCODE:
|
|
{
|
|
return CtrlUCodeUpload( demod, (pDRXUCodeInfo_t) ctrlData, UCODE_VERIFY, FALSE );
|
|
}
|
|
break;
|
|
#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
|
|
case DRX_CTRL_VALIDATE_UCODE:
|
|
{
|
|
return CtrlValidateUCode (demod);
|
|
}
|
|
break;
|
|
default:
|
|
return (DRX_STS_FUNC_NOT_AVAILABLE);
|
|
}
|
|
return (DRX_STS_OK);
|
|
}
|
|
/* END OF FILE */
|