提交SMOD ATSC IMX APP版本 V122

This commit is contained in:
2026-07-16 14:35:59 +08:00
commit 7601c270d5
485 changed files with 255032 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
VPATH += $(ROOT_DIR)/app/sonytuner/source/atsc
C_SOURCE += sony_demod_atsc_monitor.c
C_SOURCE += sony_demod_atsc.c
C_SOURCE += sony_integ_atsc.c
C_SOURCE += sony_integ_atsc3.c
+19
View File
@@ -0,0 +1,19 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
/**
@file sony_atsc.h
This file provides ATSC related type definitions.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_ATSC_H
#define SONY_ATSC_H
#include "../sony_common.h"
#endif /* SONY_ATSC_H */
+528
View File
@@ -0,0 +1,528 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/09/28
Modification ID : 1ea04def104d657deb64f0d0b0cae6ef992a9dd8
------------------------------------------------------------------------------*/
/**
@file sony_atsc3.h
This file provides ATSC 3.0 related type definitions.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_ATSC3_H
#define SONY_ATSC3_H
#include "../sony_common.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_ATSC3_NUM_PLP_MAX 64 /**< Max number of PLPs */
/*------------------------------------------------------------------------------
Enumerations
------------------------------------------------------------------------------*/
/**
@brief System bandwidth signaled in bootstrap.
*/
typedef enum {
SONY_ATSC3_SYSTEM_BW_6_MHZ, /**< 6MHz */
SONY_ATSC3_SYSTEM_BW_7_MHZ, /**< 7MHz */
SONY_ATSC3_SYSTEM_BW_8_MHZ, /**< 8MHz */
SONY_ATSC3_SYSTEM_BW_OVER_8_MHZ /**< Greater than 8 MHz */
} sony_atsc3_system_bw_t;
/**
@brief Preamble pilot pattern signaled in bootstrap.
*/
typedef enum {
SONY_ATSC3_PREAMBLE_PILOT_3, /**< Dx = 3 */
SONY_ATSC3_PREAMBLE_PILOT_4, /**< Dx = 4 */
SONY_ATSC3_PREAMBLE_PILOT_6, /**< Dx = 6 */
SONY_ATSC3_PREAMBLE_PILOT_8, /**< Dx = 8 */
SONY_ATSC3_PREAMBLE_PILOT_12, /**< Dx = 12 */
SONY_ATSC3_PREAMBLE_PILOT_16, /**< Dx = 16 */
SONY_ATSC3_PREAMBLE_PILOT_24, /**< Dx = 24 */
SONY_ATSC3_PREAMBLE_PILOT_32, /**< Dx = 32 */
} sony_atsc3_preamble_pilot_t;
/**
@brief L1-Basic fec type signaled in bootstrap.
*/
typedef enum {
SONY_ATSC3_L1B_FEC_TYPE_MODE1, /**< Mode 1 */
SONY_ATSC3_L1B_FEC_TYPE_MODE2, /**< Mode 2 */
SONY_ATSC3_L1B_FEC_TYPE_MODE3, /**< Mode 3 */
SONY_ATSC3_L1B_FEC_TYPE_MODE4, /**< Mode 4 */
SONY_ATSC3_L1B_FEC_TYPE_MODE5, /**< Mode 5 */
SONY_ATSC3_L1B_FEC_TYPE_MODE6, /**< Mode 6 */
SONY_ATSC3_L1B_FEC_TYPE_MODE7, /**< Mode 7 */
SONY_ATSC3_L1B_FEC_TYPE_RESERVED /**< Reserved */
} sony_atsc3_l1b_fec_type_t;
/**
@brief Presence or absence of timing information, and precision indicator signaled in L1-Basic.
*/
typedef enum {
SONY_ATSC3_TIME_INFO_FLAG_NONE, /**< Time information is not included */
SONY_ATSC3_TIME_INFO_FLAG_MS, /**< ms precision */
SONY_ATSC3_TIME_INFO_FLAG_US, /**< us precision */
SONY_ATSC3_TIME_INFO_FLAG_NS /**< ns precision */
} sony_atsc3_time_info_flag_t;
/**
@brief PAPR (Peak to Average Power Ratio) reduction indicator signaled in L1-Basic.
*/
typedef enum {
SONY_ATSC3_PAPR_NONE, /**< No PAPR reduction used */
SONY_ATSC3_PAPR_TR, /**< Tone reservation only */
SONY_ATSC3_PAPR_ACE, /**< ACE (Active Constellation Extension) only */
SONY_ATSC3_PAPR_TR_ACE /**< Both TR and ACE */
} sony_atsc3_papr_t;
/**
@brief L1-Detail fec type signaled in L1-Basic.
*/
typedef enum {
SONY_ATSC3_L1D_FEC_TYPE_MODE1, /**< Mode 1 */
SONY_ATSC3_L1D_FEC_TYPE_MODE2, /**< Mode 2 */
SONY_ATSC3_L1D_FEC_TYPE_MODE3, /**< Mode 3 */
SONY_ATSC3_L1D_FEC_TYPE_MODE4, /**< Mode 4 */
SONY_ATSC3_L1D_FEC_TYPE_MODE5, /**< Mode 5 */
SONY_ATSC3_L1D_FEC_TYPE_MODE6, /**< Mode 6 */
SONY_ATSC3_L1D_FEC_TYPE_MODE7, /**< Mode 7 */
SONY_ATSC3_L1D_FEC_TYPE_RESERVED /**< Reserved */
} sony_atsc3_l1d_fec_type_t;
/**
@brief MISO (Multiple Input Single Output) option used in L1-Basic and L1-Detail.
*/
typedef enum {
SONY_ATSC3_MISO_NONE, /**< No MISO */
SONY_ATSC3_MISO_64, /**< MISO with 64 coefficients */
SONY_ATSC3_MISO_256, /**< MISO with 256 coefficients */
SONY_ATSC3_MISO_RESERVED /**< Reserved */
} sony_atsc3_miso_t;
/**
@brief FFT size indicator used in L1-Basic and L1-Detail.
*/
typedef enum {
SONY_ATSC3_FFT_SIZE_8K, /**< 8K */
SONY_ATSC3_FFT_SIZE_16K, /**< 16K */
SONY_ATSC3_FFT_SIZE_32K, /**< 32K */
SONY_ATSC3_FFT_SIZE_RESERVED /**< Reserved */
} sony_atsc3_fft_size_t;
/**
@brief Guard interval indicator used in L1-Basic and L1-Detail.
*/
typedef enum {
SONY_ATSC3_GI_RESERVED_0, /**< Reserved */
SONY_ATSC3_GI_1_192, /**< 1/192 */
SONY_ATSC3_GI_2_384, /**< 2/384 */
SONY_ATSC3_GI_3_512, /**< 3/512 */
SONY_ATSC3_GI_4_768, /**< 4/768 */
SONY_ATSC3_GI_5_1024, /**< 5/1024 */
SONY_ATSC3_GI_6_1536, /**< 6/1536 */
SONY_ATSC3_GI_7_2048, /**< 7/2048 */
SONY_ATSC3_GI_8_2432, /**< 8/2432 */
SONY_ATSC3_GI_9_3072, /**< 9/3072 */
SONY_ATSC3_GI_10_3648, /**< 10/3648 */
SONY_ATSC3_GI_11_4096, /**< 11/4096 */
SONY_ATSC3_GI_12_4864, /**< 12/4864 */
SONY_ATSC3_GI_RESERVED_13, /**< Reserved */
SONY_ATSC3_GI_RESERVED_14, /**< Reserved */
SONY_ATSC3_GI_RESERVED_15 /**< Reserved */
} sony_atsc3_gi_t;
/**
@brief Scattered pilot pattern indicator signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_SP_3_2, /**< SP3_2 for SISO, MP3_2 for MISO */
SONY_ATSC3_SP_3_4, /**< SP3_4 for SISO, MP3_4 for MISO */
SONY_ATSC3_SP_4_2, /**< SP4_2 for SISO, MP4_2 for MISO */
SONY_ATSC3_SP_4_4, /**< SP4_4 for SISO, MP4_4 for MISO */
SONY_ATSC3_SP_6_2, /**< SP6_2 for SISO, MP6_2 for MISO */
SONY_ATSC3_SP_6_4, /**< SP6_4 for SISO, MP6_4 for MISO */
SONY_ATSC3_SP_8_2, /**< SP8_2 for SISO, MP8_2 for MISO */
SONY_ATSC3_SP_8_4, /**< SP8_4 for SISO, MP8_4 for MISO */
SONY_ATSC3_SP_12_2, /**< SP12_2 for SISO, MP12_2 for MISO */
SONY_ATSC3_SP_12_4, /**< SP12_4 for SISO, MP12_4 for MISO */
SONY_ATSC3_SP_16_2, /**< SP16_2 for SISO, MP16_2 for MISO */
SONY_ATSC3_SP_16_4, /**< SP16_4 for SISO, MP16_4 for MISO */
SONY_ATSC3_SP_24_2, /**< SP24_2 for SISO, MP24_2 for MISO */
SONY_ATSC3_SP_24_4, /**< SP24_4 for SISO, MP24_4 for MISO */
SONY_ATSC3_SP_32_2, /**< SP32_2 for SISO, MP32_2 for MISO */
SONY_ATSC3_SP_32_4, /**< SP32_4 for SISO, MP32_4 for MISO */
SONY_ATSC3_SP_RESERVED_16, /**< Reserved */
SONY_ATSC3_SP_RESERVED_17, /**< Reserved */
SONY_ATSC3_SP_RESERVED_18, /**< Reserved */
SONY_ATSC3_SP_RESERVED_19, /**< Reserved */
SONY_ATSC3_SP_RESERVED_20, /**< Reserved */
SONY_ATSC3_SP_RESERVED_21, /**< Reserved */
SONY_ATSC3_SP_RESERVED_22, /**< Reserved */
SONY_ATSC3_SP_RESERVED_23 /**< Reserved */
} sony_atsc3_sp_t;
/**
@brief PLP FEC type definition signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_FEC_BCH_LDPC_16K, /**< BCH + 16K LDPC */
SONY_ATSC3_PLP_FEC_BCH_LDPC_64K, /**< BCH + 64K LDPC */
SONY_ATSC3_PLP_FEC_CRC_LDPC_16K, /**< CRC + 16K LDPC */
SONY_ATSC3_PLP_FEC_CRC_LDPC_64K, /**< CRC + 64K LDPC */
SONY_ATSC3_PLP_FEC_LDPC_16K, /**< 16K LDPC only */
SONY_ATSC3_PLP_FEC_LDPC_64K, /**< 64K LDPC only */
SONY_ATSC3_PLP_FEC_RESERVED_6, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_7, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_8, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_9, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_10, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_11, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_12, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_13, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_14, /**< Reserved */
SONY_ATSC3_PLP_FEC_RESERVED_15 /**< Reserved */
} sony_atsc3_plp_fec_t;
/**
@brief PLP modulation signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_MOD_QPSK, /**< QPSK */
SONY_ATSC3_PLP_MOD_16QAM, /**< 16QAM-NUC */
SONY_ATSC3_PLP_MOD_64QAM, /**< 64QAM-NUC */
SONY_ATSC3_PLP_MOD_256QAM, /**< 256QAM-NUC */
SONY_ATSC3_PLP_MOD_1024QAM, /**< 1024QAM-NUC */
SONY_ATSC3_PLP_MOD_4096QAM, /**< 4096QAM-NUC */
SONY_ATSC3_PLP_MOD_RESERVED_6, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_7, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_8, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_9, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_10, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_11, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_12, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_13, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_14, /**< Reserved */
SONY_ATSC3_PLP_MOD_RESERVED_15 /**< Reserved */
} sony_atsc3_plp_mod_t;
/**
@brief PLP code rate signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_COD_2_15, /**< 2/15 */
SONY_ATSC3_PLP_COD_3_15, /**< 3/15 */
SONY_ATSC3_PLP_COD_4_15, /**< 4/15 */
SONY_ATSC3_PLP_COD_5_15, /**< 5/15 */
SONY_ATSC3_PLP_COD_6_15, /**< 6/15 */
SONY_ATSC3_PLP_COD_7_15, /**< 7/15 */
SONY_ATSC3_PLP_COD_8_15, /**< 8/15 */
SONY_ATSC3_PLP_COD_9_15, /**< 9/15 */
SONY_ATSC3_PLP_COD_10_15, /**< 10/15 */
SONY_ATSC3_PLP_COD_11_15, /**< 11/15 */
SONY_ATSC3_PLP_COD_12_15, /**< 12/15 */
SONY_ATSC3_PLP_COD_13_15, /**< 13/15 */
SONY_ATSC3_PLP_COD_RESERVED_12, /**< Reserved */
SONY_ATSC3_PLP_COD_RESERVED_13, /**< Reserved */
SONY_ATSC3_PLP_COD_RESERVED_14, /**< Reserved */
SONY_ATSC3_PLP_COD_RESERVED_15 /**< Reserved */
} sony_atsc3_plp_cod_t;
/**
@brief PLP time interleaving mode signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_TI_NONE, /**< No time interleaving mode */
SONY_ATSC3_PLP_TI_CTI, /**< Convolutional time interleaving */
SONY_ATSC3_PLP_TI_HTI, /**< Hybrid time interleaving */
SONY_ATSC3_PLP_TI_RESERVED /**< Reserved */
} sony_atsc3_plp_ti_t;
/**
@brief PLP channel bonding format signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_CH_BOND_FMT_PLAIN, /**< Plain channel bonding */
SONY_ATSC3_PLP_CH_BOND_FMT_SNR, /**< SNR averaged channel bonding */
SONY_ATSC3_PLP_CH_BOND_FMT_RESERVED_2, /**< Reserved */
SONY_ATSC3_PLP_CH_BOND_FMT_RESERVED_3 /**< Reserved */
} sony_atsc3_plp_ch_bond_fmt_t;
/**
@brief Number of rows used in the CTI signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_CTI_DEPTH_512, /**< 512 */
SONY_ATSC3_PLP_CTI_DEPTH_724, /**< 724 */
SONY_ATSC3_PLP_CTI_DEPTH_887_1254, /**< 887 (non-extended interleaving) or 1254 (extended interleaving) */
SONY_ATSC3_PLP_CTI_DEPTH_1024_1448, /**< 1024 (non-extended interleaving) or 1448 (extended interleaving) */
SONY_ATSC3_PLP_CTI_DEPTH_RESERVED_4, /**< Reserved */
SONY_ATSC3_PLP_CTI_DEPTH_RESERVED_5, /**< Reserved */
SONY_ATSC3_PLP_CTI_DEPTH_RESERVED_6, /**< Reserved */
SONY_ATSC3_PLP_CTI_DEPTH_RESERVED_7 /**< Reserved */
} sony_atsc3_plp_cti_depth_t;
/**
@brief Enhanced PLP's injection level signaled in L1-Detail.
*/
typedef enum {
SONY_ATSC3_PLP_LDM_INJ_LEVEL_0_0, /**< 0.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_0_5, /**< 0.5 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_1_0, /**< 1.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_1_5, /**< 1.5 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_2_0, /**< 2.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_2_5, /**< 2.5 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_3_0, /**< 3.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_3_5, /**< 3.5 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_4_0, /**< 4.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_4_5, /**< 4.5 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_5_0, /**< 5.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_6_0, /**< 6.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_7_0, /**< 7.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_8_0, /**< 8.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_9_0, /**< 9.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_10_0, /**< 10.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_11_0, /**< 11.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_12_0, /**< 12.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_13_0, /**< 13.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_14_0, /**< 14.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_15_0, /**< 15.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_16_0, /**< 16.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_17_0, /**< 17.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_18_0, /**< 18.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_19_0, /**< 19.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_20_0, /**< 20.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_21_0, /**< 21.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_22_0, /**< 22.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_23_0, /**< 23.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_24_0, /**< 24.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_25_0, /**< 25.0 dB */
SONY_ATSC3_PLP_LDM_INJ_LEVEL_RESERVED, /**< Reserved */
} sony_atsc3_plp_ldm_inj_level_t;
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief ATSC 3.0 bootstrap information.
*/
typedef struct sony_atsc3_bootstrap_t {
uint8_t bw_diff; /**< If 1, system bandwidth setting is different from signal. */
sony_atsc3_system_bw_t system_bw; /**< Signal system bandwidth. */
uint8_t ea_wake_up; /**< Emergency alert wake up field. (2bit) */
} sony_atsc3_bootstrap_t;
/**
@brief ATSC 3.0 parameters estimated by demodulator.
@note Several parameters can be found in bootstrap, L1 too.
But note that they may NOT be latest L1 data received by demod.
These parameters are currently used by demodulator circuit.
*/
typedef struct sony_atsc3_ofdm_t {
sony_atsc3_system_bw_t system_bw; /**< System bandwidth. (6 or 7 or 8) */
uint8_t bs_num_symbol; /**< Number of bootstrap symbol - 1 */
uint8_t num_subframe; /**< Number of subframe - 1 */
sony_atsc3_l1b_fec_type_t l1b_fec_type; /**< L1-Basic fec type */
sony_atsc3_papr_t papr; /**< PAPR reduction */
uint8_t pb_num_symbol; /**< Number of preamble symbol - 1 */
sony_atsc3_fft_size_t pb_fft_size; /**< Preamble FFT size */
sony_atsc3_preamble_pilot_t pb_pilot; /**< Preamble pilot pattern */
uint8_t pb_reduced_carriers; /**< Cred_coeff indicator for preamble (0 - 4) */
sony_atsc3_gi_t pb_gi; /**< Preamble guard interval */
sony_atsc3_fft_size_t sf0_fft_size; /**< Subframe #0 FFT size */
sony_atsc3_sp_t sf0_sp; /**< Subframe #0 scattered pilot pattern */
uint8_t sf0_reduced_carriers;/**< Cred_coeff indicator for subframe #0 (0 - 4) */
sony_atsc3_gi_t sf0_gi; /**< Subframe #0 guard interval */
uint8_t sf0_sp_boost; /**< Subframe #0 scattered pilot boost (0 - 4) */
uint8_t sf0_sbs_first; /**< Subframe #0 subframe boundary symbol first flag */
uint8_t sf0_sbs_last; /**< Subframe #0 subframe boundary symbol last flag */
uint16_t sf0_num_ofdm_symbol; /**< Subframe #0 number of data payload OFDM symbols - 1 */
} sony_atsc3_ofdm_t;
/**
@brief ATSC 3.0 L1-Basic information.
*/
typedef struct sony_atsc3_l1basic_t {
/* System and Frame Parameters */
uint8_t version; /**< L1-Basic structure version. (currently 0) */
uint8_t mimo_sp_enc; /**< MIMO pilot encoding scheme (0 or 1) */
uint8_t lls_flg; /**< Presence or absence of Low Level Signaling (LLS) */
sony_atsc3_time_info_flag_t time_info_flg; /**< Presence or absence, and precision of timing information */
uint8_t return_ch_flg; /**< Dedicated return channel (DRC) is present or not */
sony_atsc3_papr_t papr; /**< PAPR reduction */
uint8_t frame_length_mode; /**< Frame is time-aligned (0) or symbol-aligned (1) */
/* Valid if frame_length_mode == 0 (time-aligned frame) */
uint16_t frame_length; /**< Frame length (5ms unit) */
uint16_t excess_smp_per_sym; /**< Additional number of excess samples included in the guard interval */
/* Valid if frame_length_mode == 1 (symbol-aligned frame) */
uint16_t time_offset; /**< Number of sample periods */
uint8_t additional_smp; /**< Number of additional samples at the end of frames */
/* endif */
uint8_t num_subframe; /**< Number of subframe - 1 */
/* Parameters for L1-Detail */
uint8_t pb_num_symbol; /**< Number of preamble symbol - 1 */
uint8_t pb_reduced_carriers; /**< Cred_coeff indicator for preamble (0 - 4) */
uint8_t l1d_content_tag; /**< Incremented if L1-Detail content is modified */
uint16_t l1d_size; /**< L1-Detail information size (byte) */
sony_atsc3_l1d_fec_type_t l1d_fec_type; /**< L1-Detail fec type */
uint8_t l1d_add_parity_mode; /**< L1-Detail Additional parity mode (0 - 2) */
uint32_t l1d_total_cells; /**< The total size (specified in OFDM cells) of L1-Detail signaling */
/* Parameters for First Subframe */
uint8_t sf0_mimo; /**< Subframe #0 MIMO or not */
sony_atsc3_miso_t sf0_miso; /**< Subframe #0 MISO option */
sony_atsc3_fft_size_t sf0_fft_size; /**< Subframe #0 FFT size */
uint8_t sf0_reduced_carriers;/**< Cred_coeff indicator for subframe #0 (0 - 4) */
sony_atsc3_gi_t sf0_gi; /**< Subframe #0 guard interval */
uint16_t sf0_num_ofdm_symbol; /**< Subframe #0 number of data payload OFDM symbols - 1 */
sony_atsc3_sp_t sf0_sp; /**< Subframe #0 scattered pilot pattern */
uint8_t sf0_sp_boost; /**< Subframe #0 scattered pilot boost (0 - 4) */
uint8_t sf0_sbs_first; /**< Subframe #0 subframe boundary symbol first flag */
uint8_t sf0_sbs_last; /**< Subframe #0 subframe boundary symbol last flag */
/* Miscellaneous Parameters */
uint8_t reserved[6]; /**< Reserved for future use */
} sony_atsc3_l1basic_t;
/**
@brief ATSC 3.0 L1-Detail information raw data.
*/
typedef struct sony_atsc3_l1detail_raw_t {
uint16_t size; /**< L1-Detail information size (byte) */
uint8_t data[8191]; /**< Raw data buffer */
} sony_atsc3_l1detail_raw_t;
/**
@brief ATSC 3.0 L1-Detail common information.
*/
typedef struct sony_atsc3_l1detail_common_t {
uint8_t version; /**< L1-Detail structure version */
uint8_t num_rf; /**< Number of other frequencies in channel bonding (0 or 1) */
uint16_t bonded_bsid; /**< BSID of separate RF channel (valid if num_rf == 1) */
/* Valid if time_info_flg (sony_atsc3_l1base_t) != NONE */
uint32_t time_sec; /**< Time information (sec) */
uint16_t time_msec; /**< Time information (msec) */
/* Valid if time_info_flg (sony_atsc3_l1base_t) == US or NS */
uint16_t time_usec; /**< Time information (usec) */
/* Valid if time_info_flg (sony_atsc3_l1base_t) == NS */
uint16_t time_nsec; /**< Time information (nsec) */
uint16_t bsid; /**< BSID of the current channel */
uint16_t reserved_bitlen; /**< Size of reserved data (bit) */
} sony_atsc3_l1detail_common_t;
/**
@brief ATSC 3.0 L1-Detail subframe specific information.
*/
typedef struct sony_atsc3_l1detail_subframe_t {
uint8_t index; /**< Subframe index */
uint8_t mimo; /**< MIMO or not */
sony_atsc3_miso_t miso; /**< MISO option */
sony_atsc3_fft_size_t fft_size; /**< FFT size */
uint8_t reduced_carriers; /**< Cred_coeff indicator (0 - 4) */
sony_atsc3_gi_t gi; /**< Guard interval */
uint16_t num_ofdm_symbol; /**< Number of data payload OFDM symbols - 1 */
sony_atsc3_sp_t sp; /**< Scattered pilot pattern */
uint8_t sp_boost; /**< Scattered pilot boost (0 - 4) */
uint8_t sbs_first; /**< Subframe boundary symbol first flag */
uint8_t sbs_last; /**< Subframe boundary symbol last flag */
/* Valid if num_subframe (sony_atsc3_l1base_t) > 0 */
uint8_t subframe_mux; /**< Time-division multiplexed or concatenated in time */
uint8_t freq_interleaver; /**< Frequency interleaver is enabled or not */
/* Valid if sbs_first || sbs_last */
uint16_t sbs_null_cells; /**< Number of null cells */
uint8_t num_plp; /**< Number of PLPs in the current subframe */
} sony_atsc3_l1detail_subframe_t;
/**
@brief ATSC 3.0 L1-Detail PLP specific information.
*/
typedef struct sony_atsc3_l1detail_plp_t {
uint8_t id; /**< PIP ID (0 - 63) assigned uniquely in each RF channel */
uint8_t lls_flg; /**< Current PLP contains LLS information or not */
uint8_t layer; /**< Layer index of current PLP (0 (Core Layer) or 1 (Enhanced Layer)) */
uint32_t start; /**< First data cell index */
uint32_t size; /**< Number of data cells allocated to the current PLP */
uint8_t scrambler_type; /**< Choice of scrambler (only 0 in current version) */
sony_atsc3_plp_fec_t fec_type; /**< PLP FEC method */
sony_atsc3_plp_mod_t mod; /**< PLP modulation */
sony_atsc3_plp_cod_t cod; /**< PLP code rate */
sony_atsc3_plp_ti_t ti_mode; /**< PLP time interleaving mode */
/* Valid if ti_mode == SONY_ATSC3_PLP_TI_NONE */
uint16_t fec_block_start; /**< Start position of the first FEC Block */
/* Valid if ti_mode == SONY_ATSC3_PLP_TI_CTI */
uint32_t cti_fec_block_start; /**< Position for CTI. (See spec) */
/* Valid if num_rf (sony_atsc3_l1detail_common_t) > 0 */
uint8_t num_ch_bonded; /**< Number of other frequencies in channel bonding for this PLP (0 or 1)*/
/* Valid if num_ch_bonded > 0 */
sony_atsc3_plp_ch_bond_fmt_t ch_bonding_format; /**< Channel bonding format for the current PLP */
uint8_t bonded_rf_id_0; /**< Bonded RF ID #0 */
uint8_t bonded_rf_id_1; /**< Bonded RF ID #1 */
/* Valid if mimo (sony_atsc3_l1detail_subframe_t) == 1 */
uint8_t mimo_stream_combine; /**< Stream combining option is used or not */
uint8_t mimo_iq_interleave; /**< IQ polarization interleaving option is used or not */
uint8_t mimo_ph; /**< Phase hopping option is used nor not */
/* Valid if layer (sony_atsc3_l1detail_plp_t) == 0 */
uint8_t plp_type; /**< Current PLP is non-dispersed (0) or dispersed (1) */
/* Valid if plp_type == 1 */
uint16_t num_subslice; /**< Number of subslice - 1 (1 - 16383) */
uint32_t subslice_interval; /**< Subslice interval (data cell unit) */
/* Valid if ti_mode == SONY_ATSC3_PLP_TI_CTI or
(ti_mode == SONY_ATSC3_PLP_TI_HTI and mod == SONY_ATSC3_PLP_MOD_QPSK) */
uint8_t ti_ext_interleave; /**< Extended interleaving is used or not */
/* Valid if ti_mode == SONY_ATSC3_PLP_TI_CTI */
sony_atsc3_plp_cti_depth_t cti_depth; /**< Number of rows used in the Convolutional Time Interleaver */
uint16_t cti_start_row; /**< Position of the interleaver selector at the start of the subframe*/
/* Valid if ti_mode == SONY_ATSC3_PLP_TI_HTI */
uint8_t hti_inter_subframe; /**< HTI is used or not in this subframe */
uint8_t hti_num_ti_blocks; /**< Number of TI blocks - 1 (0 - 15) */
uint16_t hti_num_fec_block_max; /**< Maximum number of FEC Blocks - 1 */
uint16_t hti_num_fec_block[16]; /**< Number of FEC Blocks - 1 */
uint8_t hti_cell_interleave; /**< Cell Interleaver is used or not */
/* Valid if layer (sony_atsc3_l1detail_plp_t) != 0 */
sony_atsc3_plp_ldm_inj_level_t ldm_inj_level; /**< Enhanced PLP's injection level */
} sony_atsc3_l1detail_plp_t;
/**
@brief Minimum required PLP information got by ::sony_demod_atsc3_monitor_PLPList.
*/
typedef struct sony_atsc3_plp_list_entry_t {
uint8_t id; /**< PIP ID (0 - 63) assigned uniquely in each RF channel */
uint8_t lls_flg; /**< PLP contains LLS information or not */
uint8_t layer; /**< Layer index of current PLP (0 (Core Layer) or 1 (Enhanced Layer)) */
uint8_t chbond; /**< The PLP is channel bonded or not */
} sony_atsc3_plp_list_entry_t;
typedef struct sony_atsc3_plp_list_t {
uint8_t plpnum;
sony_atsc3_plp_list_entry_t plplist[SONY_ATSC3_NUM_PLP_MAX];
uint8_t actual_tun_plpnum;
} sony_atsc3_plp_list;
/**
@brief Quick PLP parameter monitor values for ::sony_demod_atsc3_monitor_FecModCod.
*/
typedef struct sony_atsc3_plp_fecmodcod_t {
uint8_t valid; /**< This PLP is valid or not */
sony_atsc3_plp_fec_t fec_type; /**< PLP FEC method */
sony_atsc3_plp_mod_t mod; /**< PLP modulation */
sony_atsc3_plp_cod_t cod; /**< PLP code rate */
} sony_atsc3_plp_fecmodcod_t;
#endif /* SONY_ATSC3_H */
+31
View File
@@ -0,0 +1,31 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/09/28
Modification ID : 1ea04def104d657deb64f0d0b0cae6ef992a9dd8
------------------------------------------------------------------------------*/
/**
@file sony_atsc3_chbond.h
This file provides ATSC 3.0 channel bonding related type definitions.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_ATSC3_CHBOND_H
#define SONY_ATSC3_CHBOND_H
#include "../sony_common.h"
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief ATSC 3.0 channel bonding related information in L1-Detail.
*/
typedef struct sony_atsc3_chbond_l1detail_t {
uint8_t num_rf; /**< Number of other frequencies in channel bonding (0 or 1) */
uint16_t bonded_bsid; /**< BSID of separate RF channel (valid if num_rf == 1) */
uint16_t bsid; /**< BSID of the current channel (valid if num_rf == 1) */
} sony_atsc3_chbond_l1detail_t;
#endif /* SONY_ATSC3_CHBOND_H */
+913
View File
@@ -0,0 +1,913 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/12/13
Modification ID : e402a4dcb0e51a00c34b174334c082c1211eebf1
------------------------------------------------------------------------------*/
#include "sony_demod_atsc.h"
#include "sony_demod_atsc_monitor.h"
#include <stdio.h>
/*------------------------------------------------------------------------------
Definitions
------------------------------------------------------------------------------*/
/* Wait time */
#define WAITCOMMANDRESPONSE_POLL_INTERVAL_MS (10) /**< Wait Response Polling Interval (in ms). */
#define WAITCPUIDLE_TIMEOUT_MS (1000) /**< Wait for CPU idle (in ms). */
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief Command data for ATSC demodulator core.
*/
typedef struct
{
uint8_t data[6]; /**< Command Parameters */
} sony_demod_atsc_cmd_t;
/*------------------------------------------------------------------------------
Static Function Prototypes
------------------------------------------------------------------------------*/
/**
@brief Configure the demodulator from Sleep to Active for ATSC.
*/
static sony_result_t SLtoAA(sony_demod_t * pDemod);
/**
@brief Configure the demodulator from Active ATSC to Active ATSC. Used
for changing channel parameters.
*/
static sony_result_t AAtoAA(sony_demod_t * pDemod);
/**
@brief Configure the demodulator from Active ATSC to Sleep.
*/
static sony_result_t AAtoSL(sony_demod_t * pDemod);
/**
@brief Send Command to ATSC demodulator.
*/
static sony_result_t sendCommand (sony_demod_t *pDemod,
const sony_demod_atsc_cmd_t *pCmd);
/**
@brief Get Response Data from ATSC demodulator.
*/
static sony_result_t readResponse (sony_demod_t *pDemod,
sony_demod_atsc_cmd_t *pResp,
uint8_t cmdId);
/**
@brief Demodulation Abort function.
*/
static sony_result_t demodAbort (sony_demod_t * pDemod);
/**
@brief Continuous writing function.
*/
static sony_result_t slaveRWriteMultiRegisters (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
const uint8_t* pData,
uint8_t size);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_demod_atsc_Tune (sony_demod_t * pDemod,
sony_atsc_tune_param_t * pTuneParam)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_demod_atsc_Tune");
if ((!pDemod) || (!pTuneParam)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->state == SONY_DEMOD_STATE_ACTIVE) && (pDemod->system == SONY_DTV_SYSTEM_ATSC)) {
/* Demodulator Active and set to ATSC mode */
result = AAtoAA(pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else if ((pDemod->state == SONY_DEMOD_STATE_ACTIVE) && (pDemod->system != SONY_DTV_SYSTEM_ATSC)) {
/* Demodulator Active but not ATSC mode */
result = sony_demod_Sleep(pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pDemod->system = SONY_DTV_SYSTEM_ATSC;
pDemod->bandwidth = SONY_DTV_BW_6_MHZ;
result = SLtoAA (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else if (pDemod->state == SONY_DEMOD_STATE_SLEEP) {
/* Demodulator in Sleep mode */
pDemod->system = SONY_DTV_SYSTEM_ATSC;
pDemod->bandwidth = SONY_DTV_BW_6_MHZ;
result = SLtoAA (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Update demodulator state */
pDemod->state = SONY_DEMOD_STATE_ACTIVE;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_TuneEnd (sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_demod_atsc_TuneEnd");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
}
result = sony_demod_atsc_SoftReset(pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Enable TS output */
result = sony_demod_SetStreamOutput (pDemod, 1);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
printf("demod enable ts output \n");
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_SoftReset (sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_atsc_cmd_t cmd;
SONY_TRACE_ENTER ("sony_demod_atsc_SoftReset");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
}
/* Abort Demodulation */
result = demodAbort (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Start FAT Command
* byte0:COMMANDID_STARTFAT 0xB3
* byte1:Demod Mode
* :8VSB (0x10)
* :64QAM (0x11)
* :256QAM (0x12)
* :AUTO (0x16)
* byte2:Signal Check OFF
* :SIGNALCHK_ON (0x00)
* :SIGNALCHK_OFF (0x04)
* byte3:Reserved(0x00)
* byte4:Reserved(0x00)
* byte5:Reserved(0x00)
*/
cmd.data[0] = 0xB3;
cmd.data[1] = 0x10; /* 8VSB Mode */
if (pDemod->atscAutoSignalCheckOff) {
cmd.data[2] = 0x04; /* During Scanning Signal Check Off */
}
else {
cmd.data[2] = 0x00; /* During Scanning Signal Check On */
}
cmd.data[3] = 0;
cmd.data[4] = 0;
cmd.data[5] = 0;
/* Send Command */
result = sendCommand (pDemod, &cmd);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Get Response */
result = readResponse (pDemod, &cmd, 0xB3);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Update Current Internal CPU State */
pDemod->atscCPUState = SONY_DEMOD_ATSC_CPU_STATE_BUSY;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_Sleep (sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_demod_atsc_Sleep");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
result = AAtoSL (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_CheckDemodLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock)
{
sony_result_t result = SONY_RESULT_OK;
uint8_t vqlock = 0;
uint8_t tslock = 0;
uint8_t agclock = 0;
uint8_t unlockDetected = 0;
SONY_TRACE_ENTER ("sony_demod_atsc_CheckDemodLock");
if (!pDemod || !pLock) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
*pLock = SONY_DEMOD_LOCK_RESULT_NOTDETECT;
result = sony_demod_atsc_monitor_SyncStat (pDemod, &vqlock, &agclock, &tslock, &unlockDetected);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (pDemod->atscUnlockDetection) {
if (unlockDetected) {
*pLock = SONY_DEMOD_LOCK_RESULT_UNLOCKED;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
} else {
/* the result of unlockDetect should be ignored */
unlockDetected = 0;
}
if (vqlock) {
*pLock = SONY_DEMOD_LOCK_RESULT_LOCKED;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_CheckTSLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock)
{
sony_result_t result = SONY_RESULT_OK;
uint8_t vqlock = 0;
uint8_t tslock = 0;
uint8_t agclock = 0;
uint8_t unlockDetected = 0;
SONY_TRACE_ENTER ("sony_demod_atsc_CheckTSLock");
if (!pDemod || !pLock) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
*pLock = SONY_DEMOD_LOCK_RESULT_NOTDETECT;
result = sony_demod_atsc_monitor_SyncStat (pDemod, &vqlock, &agclock, &tslock, &unlockDetected);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
//PR_TUN("dbg_pr vqlock=%d, agclock=%d, tslock=%d, unlockDetected=%d\n",vqlock, agclock, tslock, unlockDetected);
if (tslock) {
*pLock = SONY_DEMOD_LOCK_RESULT_LOCKED;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
if (pDemod->atscUnlockDetection) {
if (unlockDetected) {
*pLock = SONY_DEMOD_LOCK_RESULT_UNLOCKED;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
} else {
/* the result of unlockDetect should be ignored */
unlockDetected = 0;
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_SlaveRWriteRegister (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
uint8_t value,
uint8_t bitMask)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_atsc_cmd_t cmd;
SONY_TRACE_ENTER ("sony_demod_atsc_SlaveRWriteRegister");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) &&
(pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep or Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->atscCPUState != SONY_DEMOD_ATSC_CPU_STATE_IDLE) {
/* This api is accepted in CPU Idle State */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Write Register Command
* byte0:COMMANDID_WRITE_REG 0xC5
* byte1:Bank
* byte2:SubAddress
* byte3:Write Data
* byte4:Mask
* byte5:Reserved(0x00)
*/
cmd.data[0] = 0xC5;
cmd.data[1] = bank;
cmd.data[2] = registerAddress;
cmd.data[3] = value;
cmd.data[4] = bitMask;
cmd.data[5] = 0;
/* Send Command */
result = sendCommand(pDemod, &cmd);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
/* Get Response */
result = readResponse(pDemod, &cmd, 0xC5);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (result);
}
sony_result_t sony_demod_atsc_SlaveRReadRegister (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
uint8_t * pValue)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_atsc_cmd_t cmd;
SONY_TRACE_ENTER ("sony_demod_atsc_SlaveRReadRegister");
if (!pDemod || !pValue) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) &&
(pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep or Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->atscCPUState != SONY_DEMOD_ATSC_CPU_STATE_IDLE) {
/* This api is accepted in CPU Idle State */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/*
* Read Register Command
* byte0:COMMANDID_READ_REG 0xC6
* byte1:Bank
* byte2:SubAddress
* byte3:Reserved(0x00)
* byte4:Reserved(0x00)
* byte5:Reserved(0x00)
*/
cmd.data[0] = 0xC6;
cmd.data[1] = bank;
cmd.data[2] = registerAddress;
cmd.data[3] = 0;
cmd.data[4] = 0;
cmd.data[5] = 0;
/* Send Command */
result = sendCommand (pDemod, &cmd);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
/* Get Response */
result = readResponse (pDemod, &cmd, 0xC6);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
*pValue = cmd.data[1];
SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t SLtoAA(sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("SLtoAA");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Configure TS clock Mode and Frequency */
result = sony_demod_SetTSClockModeAndFreq (pDemod, SONY_DTV_SYSTEM_ATSC);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Set SLV-X Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set demod mode */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x17, 0x0F) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set SLV-T Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set TS/TLV mode */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA9, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Enable demod clock */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x2C, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x4B, 0x74) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x49, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x18, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
result = demodAbort (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* IF Frequency Setting */
{
uint8_t data[4];
data[0] = (uint8_t) ( pDemod->iffreqConfig.configATSC & 0xFF);
data[1] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 8) & 0xFF);
data[2] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 16) & 0xFF);
data[3] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 24) & 0xFF);
/*
* slave Bank Addr Bit Default Value Name
* ----------------------------------------------------------------------------------
* <SLV-R> A3h A1h [7:0] 8'h4F user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[7:0]
* <SLV-R> A3h A2h [7:0] 8'hC2 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[15:8]
* <SLV-R> A3h A3h [7:0] 8'hF6 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[23:16]
* <SLV-R> A3h A4h [7:0] 8'h24 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[31:24]
*/
result = slaveRWriteMultiRegisters (pDemod, 0xA3, 0xA1, data, sizeof(data));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* ASCOT Setting */
if (pDemod->tunerOptimize == SONY_DEMOD_TUNER_OPTIMIZE_SONYSILICON) {
/* ASCOT setting ON
* slave Bank Addr Bit Default Value Name
* ---------------------------------------------------------------------------------
* <SLV-R> A0h 13h [1:0] 8'h03 8'h03 vsb_gdeq_on
*/
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA0, 0x13, 0x03, 0x03);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
} else {
/* ASCOT setting OFF
* slave Bank Addr Bit Default Value Name
* ----------------------------------------------------------------------------------
* <SLV-R> A0h 13h [1:0] 8'h03 8'h00 vsb_gdeq_on
*/
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA0, 0x13, 0x00, 0x03);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if (pDemod->tunerOptimize == SONY_DEMOD_TUNER_OPTIMIZE_SONYSILICON) {
/* Filter Setting
* slave Bank Addr Bit Default Value Name
* --------------------------------------------------------------------------------
* <SLV-R> 06h A0h [7:0] 8'h31 8'h31 OHI_GDEQ_COEF01
* <SLV-R> 06h A1h [7:0] 8'hA5 8'hA5 OHI_GDEQ_COEF02
* <SLV-R> 06h A2h [7:0] 8'h2E 8'h2E OHI_GDEQ_COEF11
* <SLV-R> 06h A3h [7:0] 8'h9F 8'h9F OHI_GDEQ_COEF12
* <SLV-R> 06h A4h [7:0] 8'h2B 8'h2B OHI_GDEQ_COEF21
* <SLV-R> 06h A5h [7:0] 8'h99 8'h99 OHI_GDEQ_COEF22
* <SLV-R> 06h A6h [7:0] 8'h00 8'h00 OHI_GDEQ_COEF31
* <SLV-R> 06h A7h [7:0] 8'hCD 8'hCD OHI_GDEQ_COEF32
* <SLV-R> 06h A8h [7:0] 8'h00 8'h00 OHI_GDEQ_COEF41
* <SLV-R> 06h A9h [7:0] 8'hCD 8'hCD OHI_GDEQ_COEF42
* <SLV-R> 06h AAh [7:0] 8'h00 8'h00 OHI_GDEQ_COEF51
* <SLV-R> 06h ABh [7:0] 8'h00 8'h00 OHI_GDEQ_COEF52
* <SLV-R> 06h ACh [7:0] 8'h2B 8'h2B OHI_GDEQ_COEF61
* <SLV-R> 06h ADh [7:0] 8'h9D 8'h9D OHI_GDEQ_COEF62
*/
const uint8_t data[] = { 0x31, 0xA5, 0x2E, 0x9F, 0x2B, 0x99, 0x00, 0xCD, 0x00, 0xCD, 0x00, 0x00, 0x2B, 0x9D };
result = slaveRWriteMultiRegisters (pDemod, 0x06, 0xA0, data, sizeof(data));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* ATSC1.0 initial setting */
{
uint8_t noSignalThresh[3];
uint8_t signalThresh[3];
/*
* slave Bank Addr Bit Default Value Name
* -----------------------------------------------------------------------
* <SLV-R> A0h 6Fh [7:0] 8'h37 8'h61 dagca_no_signal_thresh[7:0]
* <SLV-R> A0h 70h [7:0] 8'h2e 8'hFB dagca_no_signal_thresh[15:8]
* <SLV-R> A0h 71h [7:0] 8'h66 8'h7F dagca_no_signal_thresh[23:16]
* <SLV-R> 09h 80h [7:0] 8'hAE 8'h61 OHI_DAGCA_NOSIG_THRESH[7:0]
* <SLV-R> 09h 81h [7:0] 8'h37 8'hFB OHI_DAGCA_NOSIG_THRESH[15:8]
* <SLV-R> 09h 82h [7:0] 8'h61 8'h7F OHI_DAGCA_NOSIG_THRESH[23:16]
* <SLV-R> A0h 73h [7:0] 8'hFC 8'h26 dagca_signal_thresh[7:0]
* <SLV-R> A0h 74h [7:0] 8'hA2 8'h49 dagca_signal_thresh[15:8]
* <SLV-R> A0h 75h [7:0] 8'h5C 8'h7C dagca_signal_thresh[23:16]
* <SLV-R> 09h 83h [7:0] 8'hAE 8'h26 OHI_DAGCA_SIG_THRESH[7:0]
* <SLV-R> 09h 84h [7:0] 8'h27 8'h49 OHI_DAGCA_SIG_THRESH[15:8]
* <SLV-R> 09h 85h [7:0] 8'h61 8'h7C OHI_DAGCA_SIG_THRESH[23:16]
* <SLV-R> 06h 71h [2:0] 8'h00 8'h05 OHI_CONST_SEL[2:0]
*/
noSignalThresh[0] = (uint8_t)(pDemod->atscNoSignalThresh & 0xFF);
noSignalThresh[1] = (uint8_t)((pDemod->atscNoSignalThresh >> 8) & 0xFF);
noSignalThresh[2] = (uint8_t)((pDemod->atscNoSignalThresh >> 16) & 0xFF);
signalThresh[0] = (uint8_t)(pDemod->atscSignalThresh & 0xFF);
signalThresh[1] = (uint8_t)((pDemod->atscSignalThresh >> 8) & 0xFF);
signalThresh[2] = (uint8_t)((pDemod->atscSignalThresh >> 16) & 0xFF);
result = slaveRWriteMultiRegisters (pDemod, 0xA0, 0x6F, noSignalThresh, sizeof(noSignalThresh));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = slaveRWriteMultiRegisters (pDemod, 0x09, 0x80, noSignalThresh, sizeof(noSignalThresh));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = slaveRWriteMultiRegisters (pDemod, 0xA0, 0x73, signalThresh, sizeof(signalThresh));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = slaveRWriteMultiRegisters (pDemod, 0x09, 0x83, signalThresh, sizeof(signalThresh));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0x06, 0x71, 0x05, 0x07);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* Spectrum Inversion Setting
* RF signal spectrum | tuner spectrum sense | Setting
* | (pDemod->confSense) | (from Demod View)
* -------------------+--------------------------+---------
* Normal | not same as RF(Normal) | 1B (Normal)
* Invert | not same as RF(Normal) | 0B (Invert)
* Normal | same as RF(Invert) | 0B (Invert)
* Invert | same as RF(Invert) | 1B (Normal)
* slave Bank Addr Bit Default Value Name
*------------------------------------------------------------------------------------------
* <SLV-R> A3h A0h [4] 8'h1B 8'h** vsb_DRPSPA_LOENGEN_POSSHIFT
*/
if (pDemod->rfSpectrumSense == pDemod->confSense){
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA3, 0xA0, 0x10, 0x10);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
} else {
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA3, 0xA0, 0x00, 0x10);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
}
/* Set SLV-T Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Disable HiZ Setting 1 (TAGC, SAGC(Hi-Z), TSVALID, TSSYNC, TSCLK) */
if (sony_i2c_SetRegisterBits (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, 0x08, 0x1F) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Disable HiZ Setting 2 */
result = sony_demod_SetTSDataPinHiZ (pDemod, 0);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (result);
}
static sony_result_t AAtoAA(sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("AAtoAA");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Disable TS output */
result = sony_demod_SetStreamOutput (pDemod, 0);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t AAtoSL(sony_demod_t * pDemod)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("AAtoSL");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Disable TS output */
result = sony_demod_SetStreamOutput (pDemod, 0);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Set SLV-T Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Enable Hi-Z setting 1 (TAGC, SAGC, TSVALID, TSSYNC, TSCLK) */
if (sony_i2c_SetRegisterBits (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, 0x1F, 0x1F) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Enable Hi-Z setting 2 */
result = sony_demod_SetTSDataPinHiZ (pDemod, 1);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = demodAbort (pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Set SLV-T Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Cancel ATSC1 setting
* slave Bank Addr Bit Default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 00h D3h [0] 8'h00 8'h00 OTSRATECTRLOFF
*/
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xD3, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set SLV-X Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x18, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x49, 0x33) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TADC setting */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x4B, 0x21) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Disable demodulator clock */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x2C, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set tstlv mode to default */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA9, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set demodulator mode to default */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x17, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sendCommand (sony_demod_t *pDemod, const sony_demod_atsc_cmd_t *pCmd)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sendCommand");
if ((!pDemod) || (!pDemod->pI2c) || (!pCmd)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Write data to 0x0A register */
result = pDemod->pI2c->WriteRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x0A, pCmd->data, sizeof(pCmd->data));
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
SONY_TRACE_RETURN (result);
}
static sony_result_t readResponse (sony_demod_t *pDemod, sony_demod_atsc_cmd_t *pResp, uint8_t cmdId)
{
sony_result_t result = SONY_RESULT_OK;
uint32_t waitTime = 0;
SONY_TRACE_ENTER ("readResponse");
if ((!pDemod) || (!pDemod->pI2c) || (!pResp)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
for (;;) {
/* Read data to 0x0A register */
result = pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x0A, pResp->data, sizeof(pResp->data));
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (pResp->data[0] == 0x00) {
/* Waiting... */
SONY_SLEEP (WAITCOMMANDRESPONSE_POLL_INTERVAL_MS);
waitTime += WAITCOMMANDRESPONSE_POLL_INTERVAL_MS;
}
else {
if (pResp->data[5] == cmdId) {
break;
}
else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
}
if (waitTime >= WAITCPUIDLE_TIMEOUT_MS) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_TIMEOUT);
}
}
/* Check Response Status */
if ((pResp->data[0] & 0x3F) == 0x30) {
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_OTHER);
}
}
static sony_result_t slaveRWriteMultiRegisters (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
const uint8_t* pData,
uint8_t size)
{
uint8_t wtimes = 0;
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("slaveRWriteMultiRegisters");
if (!pDemod || !pData ) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
for (wtimes = 0; wtimes < size; wtimes++) {
result = sony_demod_atsc_SlaveRWriteRegister (pDemod, bank, registerAddress + wtimes, *(pData + wtimes), 0xFF);
if (result != SONY_RESULT_OK){
SONY_TRACE_RETURN (result);
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t demodAbort (sony_demod_t * pDemod)
{
if (!pDemod){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
SONY_TRACE_ENTER ("demodAbort");
/* Set SLV-R Bank : 0x01 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x00, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Abort Current Demodulation
* slave Bank Addr Bit Value Name
* -------------------------------------------------------------------------------------
* <SLV-R> 01h 48h [0] 1'b1 OCPUWAKEUP
*/
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x48, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Update Current Internal CPU State */
pDemod->atscCPUState = SONY_DEMOD_ATSC_CPU_STATE_IDLE;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
+139
View File
@@ -0,0 +1,139 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
/**
@file sony_demod_atsc.h
This file provides the demodulator control interface specific to ATSC.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_DEMOD_ATSC_H
#define SONY_DEMOD_ATSC_H
#include "../sony_common.h"
#include "../sony_demod.h"
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief The tune parameters for a ATSC signal
*/
typedef struct sony_atsc_tune_param_t {
/**
@brief Center frequency in kHz of the ATSC channel.
*/
uint32_t centerFreqKHz;
} sony_atsc_tune_param_t;
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Enable acquisition on the demodulator for ATSC channels.
Called from the integration layer ::sony_integ_atsc_Tune API.
@param pDemod The demodulator instance
@param pTuneParam The tune parameters.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_Tune (sony_demod_t * pDemod,
sony_atsc_tune_param_t * pTuneParam);
/**
@brief Completes the demodulator ATSC acquisition setup.
Must be called after system specific demod and RF tunes.
Called from the integration layer ::sony_integ_atsc_Tune API.
@param pDemod The demodulator instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_TuneEnd (sony_demod_t * pDemod);
/**
@brief Soft reset the demodulator for ATSC.
The soft reset will begin the devices acquisition process.
Called from ::sony_demod_SoftReset API.
@param pDemod The demod instance.
@return SONY_RESULT_OK if successfully reset.
*/
sony_result_t sony_demod_atsc_SoftReset (sony_demod_t * pDemod);
/**
@brief Put the demodulator into ::SONY_DEMOD_STATE_SLEEP state.
Can be called from Active, Shutdown or Sleep states.
Called from the integration layer ::sony_integ_Sleep API.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_Sleep (sony_demod_t * pDemod);
/**
@brief Check ATSC demodulator lock status.
@param pDemod The demodulator instance
@param pLock Demod lock state
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_CheckDemodLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock);
/**
@brief Check ATSC TS lock status.
@param pDemod The demodulator instance
@param pLock TS lock state
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_CheckTSLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock);
/**
@brief Write 1-byte data to the demodulator register with SLV-R I2C channel.
@param pDemod The demodulator instance.
@param bank The bank number of the target demodulator registers.
@param registerAddress The register address of the target demodulator register.
@param value The value to write into demodulator register contents.
@param bitMask The mask to apply with the value.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_SlaveRWriteRegister (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
uint8_t value,
uint8_t bitMask);
/**
@brief Read 1-byte data from the demodulator register with SLV-R I2C channel.
@param pDemod The demodulator instance.
@param bank The bank number of the target demodulator registers.
@param registerAddress The register address of the target demodulator register.
@param pValue The buffer to store the demodulator register contents into.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc_SlaveRReadRegister (sony_demod_t * pDemod,
uint8_t bank,
uint8_t registerAddress,
uint8_t * pValue);
#endif /* SONY_DEMOD_ATSC_H */
Binary file not shown.
File diff suppressed because it is too large Load Diff
+244
View File
@@ -0,0 +1,244 @@
/*------------------------------------------------------------------------------
Copyright 2018-2019 Sony Semiconductor Solutions Corporation
Last Updated : 2019/10/04
Modification ID : ae1245fdaf66401838902e7214d8494b0f5e5a76
------------------------------------------------------------------------------*/
/**
@file sony_demod_atsc3.h
This file provides the demodulator control interface specific to ATSC 3.0.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_DEMOD_ATSC3_H
#define SONY_DEMOD_ATSC3_H
#include "../sony_common.h"
#include "../sony_demod.h"
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
#include "sony_demod_atsc3_chbond.h"
#endif
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief The tune parameters for a ATSC 3.0 signal
*/
typedef struct sony_atsc3_tune_param_t {
/**
@brief Center frequency in kHz of the ATSC 3.0 channel.
*/
uint32_t centerFreqKHz;
/**
@brief Bandwidth of the ATSC 3.0 channel.
*/
sony_dtv_bandwidth_t bandwidth;
/**
@brief Number of valid PLP ID in plpID[].
*/
uint8_t plpIDNum;
/**
@brief PLP IDs to select in acquisition.
*/
uint8_t plpID[4];
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
/**
@brief PLP bonding option for each PLPs.
Used only then the demod is configured as ATSC 3.0 channel bonding main/sub IC.
For main IC, the user should arrange PLP IDs on following constraints.
* plpBond[0] must be SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE or SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN
* SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB PLP cannot be located prior to
SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE or SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN PLPs
on plpID[] and plpBond[].
For example, following is invalid.
plpBond[0] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE
plpBond[1] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE
plpBond[2] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB
plpBond[3] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN
The user should change PLP ID selection order like as follows.
plpBond[0] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE
plpBond[1] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE
plpBond[2] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN
plpBond[3] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB
*/
sony_demod_atsc3_chbond_plp_bond_t plpBond[4];
#endif
} sony_atsc3_tune_param_t;
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Enable acquisition on the demodulator for ATSC 3.0 channels. Called from
the integration layer ::sony_integ_atsc3_Tune API.
@param pDemod The demodulator instance
@param pTuneParam The tune parameters.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_Tune (sony_demod_t * pDemod,
sony_atsc3_tune_param_t * pTuneParam);
/**
@brief Enable acquisition on the demodulator for ATSC 3.0 channels in EAS mode.
Called from the integration layer ::sony_integ_atsc3_EASTune API.
@param pDemod The demodulator instance
@param pTuneParam The tune parameters.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_EASTune (sony_demod_t * pDemod,
sony_atsc3_tune_param_t * pTuneParam);
/**
@brief Put the demodulator into ::SONY_DEMOD_STATE_SLEEP state. Can be called
from Active, Shutdown or Sleep states. Called from the integration layer
::sony_integ_Sleep API.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_Sleep (sony_demod_t * pDemod);
/**
@brief Completes the demodulator acquisition setup only the case for ATSC 3.0 EAS tune.
Must be called after system specific demod and RF tunes.
Called from the integration layer ::sony_integ_atsc3_EASTune API.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_EASTuneEnd (sony_demod_t * pDemod);
/**
@brief Check ATSC 3.0 demodulator lock status.
@note This API is for checking lock status in tuning stage.
After tuning (while receiving the signal),
please use sony_demod_atsc3_monitor_SyncStat instead
to check current lock status.
@param pDemod The demodulator instance
@param pLock Demod lock state
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_CheckDemodLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock);
/**
@brief Check ATSC 3.0 ALP lock status.
@note This API is for checking lock status in tuning stage.
After tuning (while receiving the signal),
please use sony_demod_atsc3_monitor_SyncStat instead
to check current lock status.
@param pDemod The demodulator instance
@param pLock TS lock state
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_CheckALPLock (sony_demod_t * pDemod,
sony_demod_lock_result_t * pLock,
uint8_t *p_syncState,
uint8_t *p_alpLockAll);
/**
@brief Setup the PLP configuration of the demodulator.
@param pDemod The demodulator instance.
@param plpIDNum Number of valid PLP ID in plpID[]. (1 - 4)
@param plpID The pointer of PLP ID 4 length array to set.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_SetPLPConfig (sony_demod_t * pDemod,
uint8_t plpIDNum,
uint8_t plpID[4]);
/**
@brief Clear BER, SNR history data for averaged BER, SNR, SQI monitors.
@note This function may be useful if the user would like to calculate
averaged BER, SNR, SQI without using old BER, SNR data.
Please check document and example code for recommended setting and sequence.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_ClearBERSNRHistory (sony_demod_t * pDemod);
/**
@brief Clear GPIO EAS latch data for GPIO EAS latch mode.
Clear GPIO EAS latch data.
Please check ::SONY_DEMOD_CONFIG_ATSC3_GPIO_EAS_PN_STATE
and ::SONY_DEMOD_CONFIG_ATSC3_GPIO_EAS_PN_TRANS too.
To output EAS state from GPIO, please check ::sony_demod_GPIOSetConfig.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_ClearGPIOEASLatch (sony_demod_t * pDemod);
/**
@brief Spectrum inversion and continuous wave auto detection.
@note Auto spectrum inversion and CW detection are enabled/disabled by ::sony_demod_SetConfig.
(::SONY_DEMOD_CONFIG_ATSC3_AUTO_SPECTRUM_INV, ::SONY_DEMOD_CONFIG_ATSC3_CW_DETECTION)
@param pDemod The demodulator instance
@param pContinueWait Lock wait flag (When this flag = 1, continue waiting Lock)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_AutoDetectSeq_UnlockCase (sony_demod_t * pDemod, uint8_t * pContinueWait);
/**
@brief Setup continuous wave tracking.
@note This API has effect only when CW detection is enabled by ::sony_demod_SetConfig.
(::SONY_DEMOD_CONFIG_ATSC3_CW_DETECTION)
@param pDemod The demodulator instance
@param pCompleted CW Tracking setting completed flag (When this flag = 1, CW tracking setting is completed)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_AutoDetectSeq_SetCWTracking (sony_demod_t * pDemod, uint8_t * pCompleted);
/**
@brief Initialize spectrum inversion and continuous wave auto detection related registers.
@param pDemod The demodulator instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_AutoDetectSeq_Init (sony_demod_t * pDemod);
#endif /* SONY_DEMOD_ATSC3_H */
Binary file not shown.
+539
View File
@@ -0,0 +1,539 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/12/13
Modification ID : e402a4dcb0e51a00c34b174334c082c1211eebf1
------------------------------------------------------------------------------*/
#include "sony_demod_atsc3_chbond.h"
#include "sony_demod_atsc3_monitor.h"
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_demod_atsc3_chbond_Enable (sony_demod_t * pDemod,
uint8_t enable)
{
SONY_TRACE_ENTER ("sony_demod_atsc3_chbond_Enable");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN)
&& (pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) {
/* Set SLV-X Bank : 0x00 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x00, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/*
* slave Bank Addr Bit Default Value Name
* --------------------------------------------------------------------------------
* <SLV-X> 00h C1h [2:0] 8'h00 8'h0x OREG_STREAMIN_EN
*
* Bit[0]: Stream input0 Bit[1]: Stream input1 Bit[2]: Stream input2
* 1: Stream input enble 0:Stream input disable
*/
/* Set Stream Input */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0xC1, enable ? pDemod->chbondStreamIn : 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
}
/* Set SLV-T Bank : 0x03 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x03) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/*
* slave Bank Addr Bit Default Value Name
* ---------------------------------------------------------------------------------------
* <SLV-T> 03h B2h [0] 8'h00 8'hxx OREG_BCHBOND0_ON
* <SLV-T> 03h B3h [0] 8'h00 8'hxx OREG_BCHBOND1_ON
* <SLV-T> 03h B4h [0] 8'h00 8'hxx OREG_BCHBOND2_ON
* <SLV-T> 03h B5h [0] 8'h00 8'hxx OREG_BCHBOND3_ON
* <SLV-T> 03h B6h [0] 8'h01 8'hxx OREG_ATSC30_CHBOND_MAIN_FLAG
*/
if (enable) {
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xB6, pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB ? 0x00 : 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
} else {
uint8_t data[] = {0x00, 0x00, 0x00, 0x00, 0x01};
if (pDemod->pI2c->WriteRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xB2, data, 5) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
}
/* Set SLV-T Bank : 0x93 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x93) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/*
* slave Bank Addr Bit Default Value Name
* ---------------------------------------------------------------------------------------
* <SLV-T> 93h F4h [7:0] 8'h23 8'h03 OREG_DCG_CGON[7:0]
*/
if (pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) {
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xF4, enable ? 0x03 : 0x23) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
}
/*
* slave Bank Addr Bit Default Value Name
* ---------------------------------------------------------------------------------------
* <SLV-T> 93h 85h [0] 8'h01 8'h00 OREG_PLP_ID_AUTO
*/
/*if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x85, enable ? 0x00 : 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}*/
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc3_chbond_SetPLPConfig (sony_demod_t * pDemod,
uint8_t plpIDNum,
uint8_t plpID[4],
sony_demod_atsc3_chbond_plp_bond_t plpBond[4])
{
int i = 0;
uint8_t data[4];
SONY_TRACE_ENTER ("sony_demod_atsc3_chbond_SetPLPConfig");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if ((pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) && (pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB)) {
/* For ATSC 3.0 channel bonding only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* plpIDNum range check */
if ((plpIDNum == 0) || (plpIDNum > 4)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* PLP ID range check */
for (i = 0; i < plpIDNum; i++) {
if (plpID[i] > 0x3F) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
}
if (pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) {
/* Main IC */
/* OREGD_PLP_ID_0_VALID should be 1 */
if ((plpBond[0] != SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE) &&
(plpBond[0] != SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
for (i = 1; i < plpIDNum; i++) {
switch (plpBond[i]) {
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE:
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN:
/* (OREGD_PLP_ID_X_VALID = 0) PLP should NOT be located prior to (OREGD_PLP_ID_X_VALID = 1) PLP */
if (plpBond[i - 1] == SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB:
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
}
} else {
/* Sub IC */
for (i = 0; i < plpIDNum; i++) {
switch (plpBond[i]) {
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE:
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB:
break;
case SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN:
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
}
}
/* Set SLV-T Bank : 0x93 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x93) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* slave Bank Addr Bit default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 93h 80h [7:0] 8'h00 8'hxx OREGD_PLP_ID_0_VALID,OREGD_PLP_ID_0_CHBVALID,OREGD_PLP_ID_0[5:0]
* <SLV-T> 93h 81h [7:0] 8'h00 8'hxx OREGD_PLP_ID_1_VALID,OREGD_PLP_ID_1_CHBVALID,OREGD_PLP_ID_1[5:0]
* <SLV-T> 93h 82h [7:0] 8'h00 8'hxx OREGD_PLP_ID_2_VALID,OREGD_PLP_ID_2_CHBVALID,OREGD_PLP_ID_2[5:0]
* <SLV-T> 93h 83h [7:0] 8'h00 8'hxx OREGD_PLP_ID_3_VALID,OREGD_PLP_ID_3_CHBVALID,OREGD_PLP_ID_3[5:0]
* <SLV-T> 93h 85h [0] 8'h01 8'h00 OREG_PLP_ID_AUTO
*/
for (i = 0; i < 4; i++) {
if (i < plpIDNum) {
if (pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) {
data[i] = plpID[i] | (plpBond[i] == SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB ? 0x40 : 0xC0);
} else {
data[i] = plpID[i] | 0x80;
}
} else {
data[i] = 0;
}
}
if (pDemod->pI2c->WriteRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, data, sizeof (data)) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* OREG_PLP_ID_AUTO should be 0 in channel bonding */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x85, 0x00) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set SLV-T Bank : 0x03 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x03) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* slave Bank Addr Bit Default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 03h B2h [0] 8'h00 8'hxx OREG_BCHBOND0_ON
* <SLV-T> 03h B3h [0] 8'h00 8'hxx OREG_BCHBOND1_ON
* <SLV-T> 03h B4h [0] 8'h00 8'hxx OREG_BCHBOND2_ON
* <SLV-T> 03h B5h [0] 8'h00 8'hxx OREG_BCHBOND3_ON
*/
for (i = 0; i < 4; i++) {
if ((i < plpIDNum) && (plpBond[i] == SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE)) {
data[i] = 0x01;
} else {
data[i] = 0x00;
}
}
if (pDemod->pI2c->WriteRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xB2, data, sizeof (data)) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set SLV-T Bank : 0x93 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x93) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Make IPLPINFO_RDY low for changing PLP without re-tuning case
*
* slave Bank Addr Bit default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 93h 9Ch [0] 1'b0 1'b1 OREGD_PLPINFO_UPD
*/
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x9C, 0x01) != SONY_RESULT_OK) {
SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc3_chbond_monitor_BondStat (sony_demod_t * pDemod,
uint8_t bondLockStat[4],
uint8_t * pBondLockAll,
uint8_t * pBondUnlockDetected)
{
uint8_t data;
int i;
SONY_TRACE_ENTER ("sony_demod_atsc3_chbond_monitor_BondStat");
if ((!pDemod) || (!bondLockStat) || (!pBondLockAll) || (!pBondUnlockDetected)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if ((pDemod->system != SONY_DTV_SYSTEM_ATSC3) || (pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN)) {
/* Only for ATSC 3.0 channel bonding main */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
*pBondUnlockDetected = 0;
/* Set SLV-T Bank : 0x9D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x9D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* slave Bank Addr Bit Name Meaning
* ----------------------------------------------------------------------------------
* <SLV-T> 9Dh 10h [0] ICHB_UNEXP_SP_OVERFLOW 0:Keep polling, 1:UnlockCallback
* <SLV-T> 9Dh 13h [4] ICHB_UNEXP_SHORTPKT_S 0:Keep polling, 1:UnlockCallback
* <SLV-T> 9Dh B0h [4] ICHB_LOCK_AND
* <SLV-T> 9Dh B0h [3] ICHB_LOCK_3
* <SLV-T> 9Dh B0h [2] ICHB_LOCK_2
* <SLV-T> 9Dh B0h [1] ICHB_LOCK_1
* <SLV-T> 9Dh B0h [0] ICHB_LOCK_0
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x10, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (data & 0x01) {
*pBondUnlockDetected = 1;
}
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x13, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (data & 0x10) {
*pBondUnlockDetected = 1;
}
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xB0, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
for (i = 0; i < 4; i++) {
bondLockStat[i] = (data >> i) & 0x01;
}
*pBondLockAll = data >> 4 & 0x01;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc3_chbond_monitor_SelectedPLPValid (sony_demod_t * pDemod,
sony_demod_atsc3_chbond_plp_valid_t plpValid[4])
{
sony_result_t result;
int i, j;
uint8_t plpIdValid[4];
uint8_t chBondValid[4];
uint8_t chBondOn[4];
uint8_t selectedPlpId[4];
uint8_t data[5];
const int plpConfigCheckTable[8][2] = {
/* Main */ /* Sub */ /* PLP_VALID CHB_VALID BCHBOND_ON */
{SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_UNUSED, SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_UNUSED}, /* 0 0 0 */
{/* Invalid Setting */ -1, /* Invalid Setting */ -1 }, /* 0 0 1 */
{SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_FROM_SUB, /* Invalid Setting */ -1 }, /* 0 1 0 */
{/* Invalid Setting */ -1, /* Invalid Setting */ -1 }, /* 0 1 1 */
{/* Invalid Setting */ -1, SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK }, /* 1 0 0 */
{/* Invalid Setting */ -1, SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK }, /* 1 0 1 */
{SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK, /* Invalid Setting */ -1 }, /* 1 1 0 */
{SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK, /* Invalid Setting */ -1 } /* 1 1 1 */
};
SONY_TRACE_ENTER ("sony_demod_atsc3_chbond_monitor_SelectedPLPValid");
if ((!pDemod) || (!plpValid)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pDemod->system != SONY_DTV_SYSTEM_ATSC3) ||
((pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN) &&
(pDemod->chbondConfig != SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB))) {
/* Not ATSC 3.0 or channel boding is not enabled */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Set SLV-T Bank : 0x93 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x93) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/*
* slave Bank Addr Bit Signal name
* --------------------------------------------------------------
* <SLV-T> 93h 10h [1] IL1D_OK
* <SLV-T> 93h 9Dh [0] IPLPINFO_RDY
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x10, data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (!(data[0] & 0x02)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x9D, data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (!(data[0] & 0x01)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* slave Bank Addr Bit default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 93h 80h [7:0] 8'h00 8'hxx OREGD_PLP_ID_0_VALID,OREGD_PLP_ID_0_CHBVALID,OREGD_PLP_ID_0[5:0]
* <SLV-T> 93h 81h [7:0] 8'h00 8'hxx OREGD_PLP_ID_1_VALID,OREGD_PLP_ID_1_CHBVALID,OREGD_PLP_ID_1[5:0]
* <SLV-T> 93h 82h [7:0] 8'h00 8'hxx OREGD_PLP_ID_2_VALID,OREGD_PLP_ID_2_CHBVALID,OREGD_PLP_ID_2[5:0]
* <SLV-T> 93h 83h [7:0] 8'h00 8'hxx OREGD_PLP_ID_3_VALID,OREGD_PLP_ID_3_CHBVALID,OREGD_PLP_ID_3[5:0]
* <SLV-T> 93h 84h [0] IPLP_SEL_ERR
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, data, 5) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
for (i = 0; i < 4; i++) {
plpIdValid[i] = (data[i] >> 7) & 0x01;
chBondValid[i] = (data[i] >> 6) & 0x01;
selectedPlpId[i] = data[i] & 0x3F;
}
/* Set SLV-T Bank : 0x03 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x03) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* slave Bank Addr Bit default Value Name
* ----------------------------------------------------------------------------------
* <SLV-T> 03h B2h [0] 8'h00 8'hxx OREG_BCHBOND0_ON
* <SLV-T> 03h B3h [0] 8'h00 8'hxx OREG_BCHBOND1_ON
* <SLV-T> 03h B4h [0] 8'h00 8'hxx OREG_BCHBOND2_ON
* <SLV-T> 03h B5h [0] 8'h00 8'hxx OREG_BCHBOND3_ON
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xB2, chBondOn, 4) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
for (i = 0; i < 4; i++) {
uint8_t index = (plpIdValid[i] << 2) + (chBondValid[i] << 1) + (chBondOn[i] & 0x01);
uint8_t isSub = pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN ? 0 : 1;
if (plpConfigCheckTable[index][isSub] == -1) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_OTHER);
} else {
plpValid[i] = (sony_demod_atsc3_chbond_plp_valid_t)plpConfigCheckTable[index][isSub];
}
}
if (data[4] & 0x01) {
/* PLP IDs are invalid */
for (i = 0; i < 4; i++) {
if (plpValid[i] == SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK) {
plpValid[i] = SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_ERR_ID;
}
}
} else {
/* PLP IDs are valid */
sony_atsc3_plp_list_entry_t plpList[SONY_ATSC3_NUM_PLP_MAX];
uint8_t numPLP;
/* Check that channel bonding configurations for each PLP are correct or not */
result = sony_demod_atsc3_monitor_PLPList (pDemod, plpList, &numPLP);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
for (i = 0; i < 4; i++) {
if (plpValid[i] == SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK) {
for (j = 0; j < numPLP; j++) {
if (selectedPlpId[i] == plpList[j].id) {
if ((chBondOn[i] & 0x01) != plpList[j].chbond) {
plpValid[i] = SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_ERR_BONDCONF;
}
break;
}
}
}
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc3_chbond_monitor_L1Detail (sony_demod_t * pDemod,
sony_atsc3_chbond_l1detail_t * pL1Detail)
{
uint8_t data[5];
SONY_TRACE_ENTER ("sony_demod_atsc3_chbond_monitor_L1Detail");
if ((!pDemod) || (!pL1Detail)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC3) {
/* Not ATSC 3.0 */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Freeze registers */
if (SLVT_FreezeReg (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Set SLV-T Bank : 0x93 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x93) != SONY_RESULT_OK) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
}
/*
* slave Bank Addr Bit Signal name
* --------------------------------------------------------------
* <SLV-T> 93h 10h [1] IL1D_OK
* <SLV-T> 93h 9Dh [0] IPLPINFO_RDY
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x10, data, 1) != SONY_RESULT_OK) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (!(data[0] & 0x02)) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x9D, data, 1) != SONY_RESULT_OK) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (!(data[0] & 0x01)) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/*
* slave Bank Addr Bit Name
* --------------------------------------------------------
* <SLV-T> 93h C0h [2:0] IL1D_NUM_RF[2:0]
* <SLV-T> 93h C1h [7:0] IL1D_BONDED_BSID[15:8]
* <SLV-T> 93h C2h [7:0] IL1D_BONDED_BSID[7:0]
* <SLV-T> 93h C3h [7:0] IL1D_BSID[15:8]
* <SLV-T> 93h C4h [7:0] IL1D_BSID[7:0]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xC0, data, 5) != SONY_RESULT_OK) {
SLVT_UnFreezeReg (pDemod);
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
SLVT_UnFreezeReg (pDemod);
pL1Detail->num_rf = data[0] & 0x07;
if (pL1Detail->num_rf == 0) {
pL1Detail->bonded_bsid = 0;
pL1Detail->bsid = 0;
} else {
pL1Detail->bonded_bsid = (data[1] << 8) | data[2];
pL1Detail->bsid = (data[3] << 8) | data[4];
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
+130
View File
@@ -0,0 +1,130 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/09/28
Modification ID : 1ea04def104d657deb64f0d0b0cae6ef992a9dd8
------------------------------------------------------------------------------*/
/**
@file sony_demod_atsc3_chbond.h
This file provides the demodulator control and monitor interface for ATSC 3.0 channel bonding.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_DEMOD_ATSC3_CHBOND_H
#define SONY_DEMOD_ATSC3_CHBOND_H
#include "../sony_demod.h"
#include "sony_atsc3_chbond.h"
/*------------------------------------------------------------------------------
Enumurations
------------------------------------------------------------------------------*/
/**
@brief PLP channel bonding configuration.
*/
typedef enum {
SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE, /**< PLP bonding enable */
SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_MAIN, /**< PLP bonding disable (from main only) */
SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_FROM_SUB /**< PLP bonding disable (from sub only) */
} sony_demod_atsc3_chbond_plp_bond_t;
/**
@brief PLP channel bonding configuration check status.
*/
typedef enum {
SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_UNUSED, /**< The PLP ID is not used */
SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_FROM_SUB, /**< The PLP is configured as input from sub IC */
SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_ERR_ID, /**< One or more PLP IDs are not found */
SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_ERR_BONDCONF, /**< PLP bond configuration is incorrect */
SONY_DEMOD_ATSC3_CHBOND_PLP_VALID_OK /**< PLP ID configuration is no problem */
} sony_demod_atsc3_chbond_plp_valid_t;
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Enable/disable ATSC 3.0 channel bonding function.
This API is called internally to enable/disable channel bonding.
@param pDemod The demodulator instance
@param enable Enable/disable setting.
- 0: Disable
- 1: Enable
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_chbond_Enable (sony_demod_t * pDemod,
uint8_t enable);
/**
@brief Setup the PLP configuration of the demodulator for channel bonding case.
@param pDemod The demodulator instance.
@param plpIDNum Number of valid PLP ID in plpID[]. (1 - 4)
@param plpID The pointer of PLP ID 4 length array to set.
@param plpBond The pointer of PLP bond option 4 length array to set.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_chbond_SetPLPConfig (sony_demod_t * pDemod,
uint8_t plpIDNum,
uint8_t plpID[4],
sony_demod_atsc3_chbond_plp_bond_t plpBond[4]);
/**
@brief Monitors the synchronisation state of the ATSC 3.0 demodulator.
@note Note that early unlock condition should be used in tuning stage ONLY
to detect that there are no desired signal in current frequency quickly.
After tuning, early unlock condition should NOT be used to
know current demodulator lock status basically.
@param pDemod The demodulator instance.
@param bondLockStat Pointer of 4 length array to store ALP lock status for each PLPs.
- 0: Bonding not locked.
- 1: Bonding locked.
@param pBondLockAll Indicates all selected valid PLPs by ::sony_demod_atsc3_chbond_SetPLPConfig are bonding locked or not.
- 0: Not all PLPs are locked.
- 1: All PLPs are locked.
@param pBondUnlockDetected Indicates the channel bonding unlock is detected.
- 0: No unlock.
- 1: Unlock detected.
@return SONY_RESULT_OK if pSyncStat, pTSLockStat is valid, otherwise an error is returned.
*/
sony_result_t sony_demod_atsc3_chbond_monitor_BondStat (sony_demod_t * pDemod,
uint8_t bondLockStat[4],
uint8_t * pBondLockAll,
uint8_t * pBondUnlockDetected);
/**
@brief Monitor the selected 4 PLPs are valid or not.
This API can check that the wrong channel bonding setting for each PLPs.
For example, the PLP is "channel bonded" but tuned as normal PLP.
Note that the tune APIs can finish successfully even if such wrong setting was done.
@param pDemod The demodulator instance.
@param plpValid Pointer of 4 length array to store PLP valid information for each PLPs.
See ::sony_demod_atsc3_chbond_plp_valid_t definition.
@return SONY_RESULT_OK if successful.
SONY_RESULT_ERROR_HW_STATE if all 4 PLPs are invalid.
*/
sony_result_t sony_demod_atsc3_chbond_monitor_SelectedPLPValid (sony_demod_t * pDemod,
sony_demod_atsc3_chbond_plp_valid_t plpValid[4]);
/**
@brief Get channel bonding related information in L1-Detail.
@param pDemod The demodulator instance.
@param pL1Detail Pointer to receive the channel bonding related L1-Detail information.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_chbond_monitor_L1Detail (sony_demod_t * pDemod,
sony_atsc3_chbond_l1detail_t * pL1Detail);
#endif /* SONY_DEMOD_ATSC3_CHBOND_H */
Binary file not shown.
File diff suppressed because it is too large Load Diff
+416
View File
@@ -0,0 +1,416 @@
/*------------------------------------------------------------------------------
Copyright 2018-2020 Sony Semiconductor Solutions Corporation
Last Updated : 2020/11/25
Modification ID : f08108eb7355363ac9e3ef592cba6f75731a51b6
------------------------------------------------------------------------------*/
/**
@file sony_demod_atsc3_monitor.h
This file provides the ATSC 3.0 demodulator monitor interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_DEMOD_ATSC3_MONITOR_H
#define SONY_DEMOD_ATSC3_MONITOR_H
#include "../sony_demod.h"
#include "sony_atsc3.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_DEMOD_ATSC3_MONITOR_PRELDPCBER_INVALID 0xFFFFFFFF /**< BER value if the BER value is invalid */
#define SONY_DEMOD_ATSC3_MONITOR_PREBCHBER_INVALID 0xFFFFFFFF /**< BER value if the BER value is invalid */
#define SONY_DEMOD_ATSC3_MONITOR_POSTBCHFER_INVALID 0xFFFFFFFF /**< FER value if the FER value is invalid */
#define SONY_DEMOD_ATSC3_MONITOR_ALPHEADERLENGTHERROR_INVALID 0xFF /**< ALP header length error value is invalid. */
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Monitors the synchronisation state of the ATSC 3.0 demodulator.
@note Note that early unlock condition should be used in tuning stage ONLY
to detect that there are no desired signal in current frequency quickly.
After tuning, early unlock condition should NOT be used to
know current demodulator lock status basically.
@param pDemod The demodulator instance.
@param pSyncStat The demodulator state.
- 0: WAIT_GO,
- 1: WAIT_AGC,
- 2: WAIT_BSDET,
- 3: WAIT_L1Basic,
- 4: WAIT_L1Detail,
- 5: WAIT_DMD_OK,
- 6: DMD_OK
@param alpLockStat Pointer of 4 length array to store ALP lock status for each PLPs.
- 0: ALP not locked.
- 1: ALP locked.
@param pALPLockAll Indicates all selected PLPs by ::sony_demod_atsc3_SetPLPConfig are locked or not.
- 0: Not all PLPs are locked.
- 1: All PLPs are locked.
@param pUnlockDetected Indicates the early unlock condition.
- 0: No early unlock.
- 1: Early unlock.
@return SONY_RESULT_OK if pSyncStat, pTSLockStat is valid, otherwise an error is returned.
*/
sony_result_t sony_demod_atsc3_monitor_SyncStat (sony_demod_t * pDemod,
uint8_t * pSyncStat,
uint8_t alpLockStat[4],
uint8_t * pALPLockAll,
uint8_t * pUnlockDetected);
/**
@brief Monitors the detected carrier offset of the currently tuned channel.
To get the estimated center frequency of the current channel:
Freq_Est = Freq_Tune + pOffset;
This function will compensate for an inverting tuner architecture if the
demodulator has been configured accordingly using ::SONY_DEMOD_CONFIG_SPECTRUM_INV
config option for ::sony_demod_SetConfig.
@param pDemod The demodulator instance.
@param pOffset The detected carrier offset in Hz.
@return SONY_RESULT_OK if pOffset is valid.
*/
sony_result_t sony_demod_atsc3_monitor_CarrierOffset (sony_demod_t * pDemod,
int32_t * pOffset);
/**
@brief Monitor the IFAGC value of the ATSC 3.0 demodulator.
Actual dB gain dependent on attached tuner.
@param pDemod The demodulator instance.
@param pIFAGC The IFAGC output register value. Range 0 - 0xFFF. Unitless.
@return SONY_RESULT_OK if pIFAGC is valid.
*/
sony_result_t sony_demod_atsc3_monitor_IFAGCOut (sony_demod_t * pDemod,
uint32_t * pIFAGC);
/**
@brief Monitor the Bootstrap data.
@param pDemod The demodulator instance.
@param pBootstrap The bootstrap data monitored.
@return SONY_RESULT_OK if successful and pBootstrap is valid.
*/
sony_result_t sony_demod_atsc3_monitor_Bootstrap (sony_demod_t * pDemod,
sony_atsc3_bootstrap_t * pBootstrap);
/**
@brief Monitor the demodulator information on the active channel.
These parameters are basically come from L1, but currently used by demodulator circuit.
@param pDemod The demodulator instance.
@param pOfdm Pointer to receive the tuning information.
@return SONY_RESULT_OK if the pPresetInfo is valid.
*/
sony_result_t sony_demod_atsc3_monitor_OFDM (sony_demod_t * pDemod,
sony_atsc3_ofdm_t * pOfdm);
/**
@brief Monitor the L1-Basic information.
@param pDemod The demodulator instance.
@param pL1Basic Pointer to receive the L1-Basic information.
@return SONY_RESULT_OK if the pL1Basic is valid.
*/
sony_result_t sony_demod_atsc3_monitor_L1Basic (sony_demod_t * pDemod,
sony_atsc3_l1basic_t * pL1Basic);
/**
@brief Monitor the L1-Basic and L1-Detail raw information.
This API read both L1-Basic and L1-Detail at the same time
because several L1-Detail members depend on L1-Basic information.
Note that this API may read many data by I2C. (depend on L1-Detail)
L1-Detail information read by this API is "raw" data.
To format it, please use sony_demod_atsc3_monitor_L1Detail_convert.
@param pDemod The demodulator instance.
@param pL1Basic Pointer to receive the L1-Basic information.
@param pL1Detail Pointer to receive the L1-Detail information raw data.
@return SONY_RESULT_OK if the pPresetInfo is valid.
*/
sony_result_t sony_demod_atsc3_monitor_L1Detail_raw (sony_demod_t * pDemod,
sony_atsc3_l1basic_t * pL1Basic,
sony_atsc3_l1detail_raw_t * pL1Detail);
/**
@brief Format L1-Detail information.
This API do not read new L1-Basic, L1-Detail information from the demod,
simply format L1-Detail raw information to structs,
sony_atsc3_l1detail_common_t, sony_atsc3_l1detail_subframe_t, sony_atsc3_l1detail_plp_t.
Note that if the specified PLP mapped to multiple subframes,
this API shows firstly found information related to the PLP.
@param pDemod The demodulator instance.
@param pL1Basic Pointer to receive the L1-Basic information.
@param pL1Detail Pointer to receive the L1-Detail information raw data.
@param plpID Target PLP ID to be read.
@param pL1DetailCommon Formatted L1-Detail information. (common part)
@param pL1DetailSubframe Formatted L1-Detail information. (subframe dependent part)
@param pL1DetailPlp Formatted L1-Detail information. (PLP dependent part)
@return SONY_RESULT_OK if the pPresetInfo is valid.
*/
sony_result_t sony_demod_atsc3_monitor_L1Detail_convert (sony_demod_t * pDemod,
sony_atsc3_l1basic_t * pL1Basic,
sony_atsc3_l1detail_raw_t * pL1Detail,
uint8_t plpID,
sony_atsc3_l1detail_common_t * pL1DetailCommon,
sony_atsc3_l1detail_subframe_t * pL1DetailSubframe,
sony_atsc3_l1detail_plp_t * pL1DetailPlp);
/**
@brief Monitor the PLP list in current RF channel.
@param pDemod The demodulator instance.
@param plpList Pointer to an array of sony_atsc3_plp_list_entry_t
that can receive the list of PLPs carried. (max length is 64)
This parameter can be NULL. If so, number of PLP is only returned.
@param pNumPLPs The number of PLPs.
@return SONY_RESULT_OK if the pPLPList and pNumPLPs are valid.
*/
sony_result_t sony_demod_atsc3_monitor_PLPList (sony_demod_t * pDemod,
sony_atsc3_plp_list_entry_t plpList[SONY_ATSC3_NUM_PLP_MAX],
uint8_t * pNumPLPs);
/**
@brief Monitor the PLP error indicator.
A PLP error is indicated
when one of the selected PLP was not found in the channel.
@param pDemod The demodulator instance.
@param pPLPError The error indicated.
- 0: No data PLP error.
- 1: Data PLP error detected.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_monitor_PLPError (sony_demod_t * pDemod,
uint8_t * pPLPError);
/**
@brief Monitor the selected 4 PLPs are valid or not.
The demodulator can correct PLP ID for single PLP case.
If so, even if specified PLP ID is not correct, tune API can be success.
This function checks such case too.
This function is used internally in common.
@param pDemod The demodulator instance.
@param plpValid Pointer of 4 length array to store PLP valid information for each PLPs.
- 0: Selected PLP is invalid.
- 1: Selected PLP is valid.
@return SONY_RESULT_OK if successful.
SONY_RESULT_ERROR_HW_STATE if all 4 PLPs are invalid.
*/
sony_result_t sony_demod_atsc3_monitor_SelectedPLPValid (sony_demod_t * pDemod,
uint8_t plpValid[4]);
/**
@brief Monitors the channel spectrum sense.
To ensure correct polarity detection
please use the ::SONY_DEMOD_CONFIG_SPECTRUM_INV config option in
::sony_demod_SetConfig to select the appropriate spectrum inversion
for the tuner output.
@param pDemod The demodulator instance.
@param pSense Indicates the spectrum sense.
@return SONY_RESULT_OK if successful and pSense is valid.
*/
sony_result_t sony_demod_atsc3_monitor_SpectrumSense (sony_demod_t * pDemod,
sony_demod_terr_cable_spectrum_sense_t * pSense);
/**
@brief Monitor the SNR estimation made by the demodulator.
Clipped to a maximum of 40dB.
@param pDemod The demodulator instance.
@param pSNR The returned SNR in dB x 1000.
@return SONY_RESULT_OK if pSNR is valid.
*/
sony_result_t sony_demod_atsc3_monitor_SNR (sony_demod_t * pDemod,
int32_t * pSNR);
/**
@brief Monitor the pre-LDPC BER.
This provides the BER for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
ber[N] will become SONY_DEMOD_ATSC3_MONITOR_PRELDPCBER_INVALID.
@param pDemod The demodulator instance.
@param ber Pointer of 4 length array to store each PLP BER. BER x 1e7 value are returned.
@return SONY_RESULT_OK if the pBER is valid.
*/
sony_result_t sony_demod_atsc3_monitor_PreLDPCBER (sony_demod_t * pDemod,
uint32_t ber[4]);
/**
@brief Monitor the pre-BCH BER.
This provides the BER for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
ber[N] will become SONY_DEMOD_ATSC3_MONITOR_PREBCHBER_INVALID.
Note that BER is supported depend on the PLP's FEC type.
- SONY_ATSC3_PLP_FEC_BCH_LDPC_16K : Supported
- SONY_ATSC3_PLP_FEC_BCH_LDPC_64K : Supported
- SONY_ATSC3_PLP_FEC_CRS_LDPC_16K : NOT supported
- SONY_ATSC3_PLP_FEC_CRS_LDPC_64K : NOT supported
- SONY_ATSC3_PLP_FEC_LDPC_16K : NOT supported
- SONY_ATSC3_PLP_FEC_LDPC_64K : NOT supported
If "NOT supported" cases, ber[N] will become SONY_DEMOD_ATSC3_MONITOR_PREBCHBER_INVALID.
@param pDemod The demodulator instance.
@param ber Pointer of 4 length array to store each PLP BER. BER x 1e9 value are returned.
@return SONY_RESULT_OK if pBER is valid.
*/
sony_result_t sony_demod_atsc3_monitor_PreBCHBER (sony_demod_t * pDemod,
uint32_t ber[4]);
/**
@brief Monitor the post BCH FER (FEC block error rate) parameters.
This provides the FER for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
fer[N] will become SONY_DEMOD_ATSC3_MONITOR_POSTBCHFER_INVALID.
Regardless of PLP FEC type, this API can return estimated FER value.
@param pDemod The demod instance.
@param fer Pointer of 4 length array to store each PLP FER. FER x 1e6 value are returned.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_monitor_PostBCHFER (sony_demod_t * pDemod,
uint32_t fer[4]);
/**
@brief Monitor the Baseband Packet Error Number in 1 sec.
This provides the Packet Error Number for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
pen[N] will become 0.
@param pDemod The demodulator instance.
@param pen Pointer of 4 length array to store each PLP Packet Error Number.
@return SONY_RESULT_OK if pPEN is valid.
*/
sony_result_t sony_demod_atsc3_monitor_BBPacketErrorNumber (sony_demod_t * pDemod,
uint32_t pen[4]);
/**
@brief Monitor the sampling frequency offset value.
@param pDemod The demodulator instance.
@param pPPM The sampling frequency offset in ppm x 100.
Range: +/- 220ppm.
@return SONY_RESULT_OK if pPPM is valid.
*/
sony_result_t sony_demod_atsc3_monitor_SamplingOffset (sony_demod_t * pDemod,
int32_t * pPPM);
/**
@brief Monitor the FEC type, Modulation, Code rate parameter for currently selected PLPs.
@param pDemod The demodulator instance.
@param fecmodcod Pointer of 4 length array to store each PLP parameters.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_demod_atsc3_monitor_FecModCod (sony_demod_t * pDemod,
sony_atsc3_plp_fecmodcod_t fecmodcod[4]);
/**
@brief Monitor the ALP header length format error for each PLPs.
This provides the ALP header length error status for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
errorStandard[N] and errorKorean[N] will become
SONY_DEMOD_ATSC3_MONITOR_ALPHEADERLENGTHERROR_INVALID (0xFF).
If FER > 0 for the PLP, ALP header length error monitor cannot return correct value.
Then errorStadard[N] and errorKorean[N] become
SONY_DEMOD_ATSC3_MONITOR_ALPHEADERLENGTHERROR_INVALID (0xFF).
@param pDemod The demodulator instance.
@param errorStandard Pointer of 4 length array to store each PLP ALP header length error status in standard mode.
@param errorKorean Pointer of 4 length array to store each PLP ALP header length error status in Korean mode.
@return SONY_RESULT_OK if errorStadard and errorKorean are valid.
*/
sony_result_t sony_demod_atsc3_monitor_ALPHeaderLengthError (sony_demod_t * pDemod,
uint8_t errorStandard[4],
uint8_t errorKorean[4]);
/**
@brief Monitor the averaged pre-BCH BER.
This provides the BER for each (max 4) PLPs.
If plpID[N] is not specified in tune API,
ber[N] will become SONY_DEMOD_ATSC3_MONITOR_PREBCHBER_INVALID.
Note that BER is supported depend on the PLP's FEC type.
- SONY_ATSC3_PLP_FEC_BCH_LDPC_16K : Supported
- SONY_ATSC3_PLP_FEC_BCH_LDPC_64K : Supported
- SONY_ATSC3_PLP_FEC_CRS_LDPC_16K : NOT supported
- SONY_ATSC3_PLP_FEC_CRS_LDPC_64K : NOT supported
- SONY_ATSC3_PLP_FEC_LDPC_16K : NOT supported
- SONY_ATSC3_PLP_FEC_LDPC_64K : NOT supported
If "NOT supported" cases, ber[N] will become SONY_DEMOD_ATSC3_MONITOR_PREBCHBER_INVALID.
@param pDemod The demodulator instance.
@param ber Pointer to array for storing each PLP BER. BER x 1e9 value are returned.
@return SONY_RESULT_OK if pBER is valid.
*/
sony_result_t sony_demod_atsc3_monitor_AveragedPreBCHBER (sony_demod_t * pDemod,
uint32_t ber[4]);
/**
@brief Monitor the estimated averaged SNR value.
Clipped to a maximum of 40dB.
@param pDemod The demodulator instance.
@param pSNR The returned SNR in dB x 1000.
@return SONY_RESULT_OK if pSNR is valid.
*/
sony_result_t sony_demod_atsc3_monitor_AveragedSNR (sony_demod_t * pDemod,
int32_t * pSNR);
#endif /* SONY_DEMOD_ATSC3_MONITOR_H */
Binary file not shown.
+991
View File
@@ -0,0 +1,991 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/12/13
Modification ID : e402a4dcb0e51a00c34b174334c082c1211eebf1
------------------------------------------------------------------------------*/
#include "sony_demod_atsc_monitor.h"
#include "../sony_math.h"
#include <string.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Static Function Prototypes
------------------------------------------------------------------------------*/
static sony_result_t checkVQLock (sony_demod_t * pDemod);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_demod_atsc_monitor_SyncStat (sony_demod_t * pDemod,
uint8_t * pVQLockStat,
uint8_t * pAGCLockStat,
uint8_t * pTSLockStat,
uint8_t * pUnlockDetected)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_SyncStat");
if ((!pDemod) || (!pVQLockStat) || (!pAGCLockStat) || (!pTSLockStat) || (!pUnlockDetected)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
}
{
uint8_t data;
/* Set SLV-M Bank : 0x0F */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0F) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* TS lock flag
* slave Bank Addr Bit Name Meaning
* -----------------------------------------------------------------------
* <SLV-M> 0Fh 11h [0] TSLOCK 0:UNLOCK, 1:LOCK
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x11, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pTSLockStat = (uint8_t)(data & 0x01);
/* Set SLV-M Bank : 0x09 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x09) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* AGC lock flag / Early Unlock Flag
* slave Bank Addr Bit Name Meaning
* -----------------------------------------------------------------------
* <SLV-M> 09h 62h [4] DAGCA_LOCK 0:UNLOCK, 1:LOCK
* <SLV-M> 09h 62h [6] ISIGNAL_PRESENCE 0:not present, 1:present
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x62, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pAGCLockStat = (uint8_t)((data & 0x10) ? 1 : 0);
*pUnlockDetected = (uint8_t)((data & 0x40) ? 0 : 1);
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* DMD lock flag
* slave Bank Addr Bit Name Meaning
* -----------------------------------------------------------------------
* <SLV-M> 0Dh 86h [0] VQLOCK 0:UNLOCK, 1:LOCK
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x86, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pVQLockStat = (uint8_t)(data & 0x01);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_IFAGCOut (sony_demod_t * pDemod,
uint32_t * pIFAGCOut)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_IFAGCOut");
if ((!pDemod) || (!pIFAGCOut)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Set SLV-M Bank : 0x09 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x09) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* IFAGC Output
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 09h 63h [7:0] DAGCA_IFMON[7:0]
* <SLV-M> 09h 64h [5:0] DAGCA_IFMON[13:8]
*/
{
uint8_t data[2];
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x63, data, 2) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pIFAGCOut = ((uint32_t)(data[1] & 0x3F) << 8) | data[0];
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_CarrierOffset (sony_demod_t * pDemod,
int32_t * pOffset)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_CarrierOffset");
if ((!pDemod) || (!pOffset)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x06 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x06) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
{
uint8_t data[3];
int32_t freqError[2];
uint32_t ctlVal = 0;
/* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 06h F8h [7:0] dpt_lfacc[7:0]
* <SLV-M> 06h F9h [7:0] dpt_lfacc[15:8]
* <SLV-M> 06h FAh [3:0] dpt_lfacc[19:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0xF8, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
ctlVal = ((uint32_t)(data[2] & 0x0F) << 16) | ((uint32_t)data[1] << 8) | data[0];
freqError[0] = sony_Convert2SComplement (ctlVal, 20); /* dpt_lfacc values reported in two's complement format */
/* 8VSB:Frequency Error[0] [Hz] = dpt_lfacc * (2^-22) * 10.762238 * 10^6
* = dpt_lfacc * 2.565917492
* = dpt_lfacc * 1155 / 450
*/
freqError[0] *= 1155;
/* Set SLV-M Bank : 0x07 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x07) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 07h 30h [7:0] dpt_ext_lfacc[7:0]
* <SLV-M> 07h 31h [7:0] dpt_ext_lfacc[15:8]
* <SLV-M> 07h 32h [3:0] dpt_ext_lfacc[19:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x30, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
ctlVal = ((uint32_t)(data[2] & 0x0F) << 16) | ((uint32_t)data[1] << 8) | data[0];
freqError[1] = sony_Convert2SComplement (ctlVal, 20); /* dpt_ext_lfacc values reported in two's complement format */
/* Frequency Error[1] [Hz] = dpt_ext_lfacc * (2^-23) * 48 * 10^6
* = dpt_ext_lfacc * 5.7220458984375
* = dpt_ext_lfacc * 3125 / 546
*/
freqError[1] *= 3125;
if ((freqError[0] + freqError[1]) >= 0) {
*pOffset = - ((freqError[0] + freqError[1] + 273) / 546);
} else {
*pOffset = - ((freqError[0] + freqError[1] - 273) / 546);
}
/* Compensate for inverted spectrum. */
if (pDemod->rfSpectrumSense == SONY_DEMOD_TERR_CABLE_SPECTRUM_INV) {
*pOffset *= -1;
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_PreRSBER (sony_demod_t * pDemod,
uint32_t * pBER)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_PreRSBER");
if ((!pDemod) || (!pBER)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
{
uint8_t data[3];
uint32_t bitError = 0;
uint32_t blocks = 0;
uint16_t bitPerBlock = 0;
uint8_t ecntEn = 0;
uint8_t overFlow = 1;
/* Before RS BER Monitor
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 90h [7:0] RSERRA_BIERR[7:0]
* <SLV-M> 0Dh 91h [7:0] RSERRA_BIERR[15:8]
* <SLV-M> 0Dh 92h [4:0] RSERRA_BIERR[20:16]
* <SLV-M> 0Dh 92h [5] RSERRA_ECNTEN
* <SLV-M> 0Dh 92h [6] RSERRA_OVF
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x90, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
ecntEn = (uint8_t)((data[2] & 0x20) ? 1 : 0);
overFlow = (uint8_t)((data[2] & 0x40) ? 1 : 0);
bitError =((uint32_t)(data[2] & 0x1F) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
if (overFlow){
*pBER = 10000000;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
if(!ecntEn){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* 8VSB: 1 Block = 207 Symbol * 8 Bit/Symbol */
bitPerBlock = 207 * 8;
/* 8VSB Measurement Block Length
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 9Ah [7:0] IRSERRA_BKLEN[7:0]
* <SLV-M> 0Dh 9Bh [7:0] IRSERRA_BKLEN[15:8]
* <SLV-M> 0Dh 9Ch [7:0] IRSERRA_BKLEN[23:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x9A, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
blocks = ((uint32_t)(data[2] & 0xFF) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0] ;
/* Check value of the blocks is valid */
if ((blocks == 0) || (blocks < (bitError / bitPerBlock))){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Case value of the blocks is not so large */
if (blocks < 0xFFFFF){
/*
* BER = bitError * 10000000 / (blocks * bitPerBlock)
* = bitError * 1000 * 5 * 5 * 5 * 10 /(blocks * (bitPerBlock / 8))
* (Divide in 5 steps to prevent overflow.)
*/
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = blocks * (bitPerBlock / 8);
Q = (bitError * 1000) / Div;
R = (bitError * 1000) % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 10;
Q = (Q * 10) + (R / Div);
R = R % Div;
/* rounding */
if (R <= (Div/2)) {
*pBER = Q;
}
else {
*pBER = Q + 1;
}
}
else {
/*
* BER = bitError * 10000000 / (blocks * bitPerBlock)
* = bitError * 625 * 5 * 5 * 5 /((blocks * (bitPerBlock / 8)) / 16)
* (Divide in 4 steps to prevent overflow.)
*/
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = (blocks * (bitPerBlock / 8)) / 16;
Q = (bitError * 625) / Div;
R = (bitError * 625) % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
/* rounding */
if (R <= (Div/2)) {
*pBER = Q;
}
else {
*pBER = Q + 1;
}
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_PreRSSER (sony_demod_t * pDemod,
uint32_t * pSER)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_PreRSSER");
if ((!pDemod) || (!pSER)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
{
uint8_t data[3];
uint32_t symbolError = 0;
uint32_t symbolPerBlock = 0;
uint32_t blocks = 0;
uint8_t ecntEn = 0;
uint8_t overFlow = 1;
/* Before RS SER Monitor
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 93h [7:0] RSERRA_SYERR[7:0]
* <SLV-M> 0Dh 94h [7:0] RSERRA_SYERR[15:8]
* <SLV-M> 0Dh 95h [1:0] RSERRA_SYERR[17:16]
* <SLV-M> 0Dh 95h [2] RSERRA_ECNTEN
* <SLV-M> 0Dh 95h [3] RSERRA_OVF
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x93, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
ecntEn = (uint8_t) ((data[2] & 0x04) ? 1 : 0);
overFlow = (uint8_t) ((data[2] & 0x08) ? 1 : 0);
symbolError = ((uint32_t)(data[2] & 0x03) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
if (overFlow){
*pSER = 10000000;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
if (!ecntEn){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* 8VSB: 1 Block = 207 Symbol */
symbolPerBlock = 207;
/* 8VSB Measurement Block Length
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 9Ah [7:0] IRSERRA_BKLEN[7:0]
* <SLV-M> 0Dh 9Bh [7:0] IRSERRA_BKLEN[15:8]
* <SLV-M> 0Dh 9Ch [7:0] IRSERRA_BKLEN[23:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x9A, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
blocks = ((uint32_t)(data[2] & 0xFF) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
/* Check value of the blocks is valid */
if ((blocks == 0) || (blocks < (symbolError / symbolPerBlock))){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Case value of the blocks is not so large */
if (blocks < 0xFFFFF){
/*
* SER = symbolError * 10000000 / (blocks * symbolPerBlock)
* = symbolError * 10000 * 10 * 10 * 10 / (blocks * symbolPerBlock)
* (Divide in 4 steps to prevent overflow.)
*/
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = blocks * symbolPerBlock;
Q = (symbolError * 10000) / Div;
R = (symbolError * 10000) % Div;
R *= 10;
Q = (Q * 10) + (R / Div);
R = R % Div;
R *= 10;
Q = (Q * 10) + (R / Div);
R = R % Div;
R *= 10;
Q = (Q * 10) + (R / Div);
R = R % Div;
/* rounding */
if (R <= (Div/2)) {
*pSER = Q;
}
else {
*pSER = Q + 1;
}
}
else {
/*
* SER = symbolError * 10000000 / (blocks * symbolPerBlock)
* = symbolError * 10000 * 5 * 5 * 5 / (blocks * symbolPerBlock / 8)
* (Divide in 4 steps to prevent overflow.)
*/
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = (blocks * symbolPerBlock) / 8;
Q = (symbolError * 10000) / Div;
R = (symbolError * 10000) % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
R *= 5;
Q = (Q * 5) + (R / Div);
R = R % Div;
/* rounding */
if (R <= (Div/2)) {
*pSER = Q;
}
else {
*pSER = Q + 1;
}
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_PostRSWER (sony_demod_t * pDemod,
uint32_t * pWER)
{
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_PostRSWER");
if ((!pDemod) || (!pWER)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
{
uint8_t data[3];
uint32_t wordError = 0;
uint32_t blocks = 0;
uint8_t ecntEn = 0;
uint8_t overFlow = 1;
/* After RS WER Monitor
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 96h [7:0] RSERRA_BKERR[7:0]
* <SLV-M> 0Dh 97h [5:0] RSERRA_BKERR[13:8]
* <SLV-M> 0Dh 97h [6] RSERRA_ECNTEN
* <SLV-M> 0Dh 97h [7] RSERRA_OVF
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x96, data, 2) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
ecntEn = (uint8_t)((data[1] & 0x40) ? 1 : 0);
overFlow = (uint8_t)((data[1] & 0x80) ? 1 : 0);
wordError = ((uint32_t)(data[1] & 0x3F) << 8) | data[0];
if (overFlow){
*pWER = 1000000;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
if (!ecntEn){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* 8VSB Measurement Block Length
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 9Ah [7:0] IRSERRA_BKLEN[7:0]
* <SLV-M> 0Dh 9Bh [7:0] IRSERRA_BKLEN[15:8]
* <SLV-M> 0Dh 9Ch [7:0] IRSERRA_BKLEN[23:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x9A, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
blocks = ((uint32_t)(data[2] & 0xFF) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
/* Check value of the blocks is valid */
if (( blocks == 0) || (blocks < wordError)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Case value of the blocks is not so large */
if (blocks < 0xFFF ){
*pWER = wordError * 1000000 / blocks; /* wordError must be smaller than blocks, then this calcuation will not be overflow */
}
else {
/*
* WER = wordError * 1000000 / blocks
* = wordError * 100000 * 10 / blocks
* (Divide in 2 steps to prevent overflow.)
*/
{
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = blocks;
Q = (wordError * 100000) / Div;
R = (wordError * 100000) % Div;
R *= 10;
Q = (Q * 10) + (R / Div);
R = R % Div;
/* rounding */
if (R <= (Div/2)) {
*pWER = Q;
}
else {
*pWER = Q + 1;
}
}
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_PacketError (sony_demod_t * pDemod,
uint8_t * pPacketErrorDetected)
{
uint8_t data = 0;
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_PacketError");
if ((!pDemod) || (!pPacketErrorDetected)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Packet Error Monitor
* slave Bank Addr Bit Name
* ------------------------------------------------------------
* <SLV-M> 0Dh 82h [0] IERR
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x82, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pPacketErrorDetected = (uint8_t)((data & 0x01) ? 1 : 0);
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_SNR (sony_demod_t * pDemod,
int32_t * pSNR)
{
uint8_t data[3];
uint32_t dcl_avgerr_fine;
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_SNR");
if ((!pDemod) || (!pSNR)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* SNR Monitor
* slave Bank Addr Bit Name
* -------------------------------------------------
* <SLV-M> 0Dh 70h [7:0] dcl_avgerr_fine[7:0]
* <SLV-M> 0Dh 71h [7:0] dcl_avgerr_fine[15:8]
* <SLV-M> 0Dh 72h [6:0] dcl_avgerr_fine[22:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x70, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
dcl_avgerr_fine = ((uint32_t)(data[2] & 0x7F) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
/* sony_log10 returns log10(x) * 100
* 8VSB: SNR[mdB] = 1000 * 10(log10( 21*8*8 / (dcl_avgerr_fine * 2^-13) ))
* = 10000 * log10( 21*2^19 / dcl_avgerr_fine )
* = 10000 * ( log10(21) + 19log10(2) -log10(dcl_avgerr_fine))
* = 70418 - 100 * sony_log10(dcl_avgerr_fine)
*/
*pSNR = (int32_t)(70418 - (100 * sony_math_log10(dcl_avgerr_fine)));
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_SamplingOffset (sony_demod_t * pDemod,
int32_t * pPPM)
{
uint8_t data[6];
uint32_t dtrLfaccHigh;
uint32_t dtrLfaccLow;
int32_t dtrlfacc;
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_SamplingOffset");
if ((!pDemod) || (!pPPM)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* VQ Lock Check */
if (checkVQLock (pDemod) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
/* Set SLV-M Bank : 0x06 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x06) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Symbol Rate
* slave Bank Addr Bit Name
* -------------------------------------------------
* <SLV-M> 06h 17h [7:0] dtr_lfacc[7:0]
* <SLV-M> 06h 18h [7:0] dtr_lfacc[15:8]
* <SLV-M> 06h 19h [7:0] dtr_lfacc[23:16]
* <SLV-M> 06h 1Ah [7:0] dtr_lfacc[31:24]
* <SLV-M> 06h 1Bh [7:0] dtr_lfacc[39:32]
* <SLV-M> 06h 1Ch [3:0] dtr_lfacc[43:40]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x17, data, 6) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
dtrLfaccLow = ((uint32_t)(data[3] & 0xFF) << 24) | ((uint32_t)(data[2] & 0xFF) << 16) | ((uint32_t)(data[1] & 0xFF) << 8) | data[0];
dtrLfaccHigh = ((uint32_t)(data[5] & 0x0F) << 8) | data[4];
/* Symbol Rate Detector Result can be calculated with the following formula.
* Detected SymbolRate[sps] = 48 / 2 / {2 * {dtr_lfacc/(2^43) + 1}} * 10^6
* =(4800 * 10^4 * 2^41) / (dtr_lfacc + 2^43)
* 18bit Shift
* ->(4800 * 10^4 * 2^23) / (dtr_lfacc/2^18 + 2^25)
*/
/* Round off LSB 18 bit and 2's Complement */
dtrlfacc = sony_Convert2SComplement (((dtrLfaccHigh & 0xFFF) << 14) | (dtrLfaccLow >> 18), 26);
if (dtrlfacc < 0){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
{
uint32_t Q = 0;
uint32_t R = 0;
uint32_t Div = 0;
int32_t symbolRateOffset = 0;
int8_t flgNegative = 1;
/* 8VSB: Detected SymbolRate[sps] = (4800 * 10^4 * 2^23) / (dtr_lfacc/2^18 + 2^25)
* = (4800 * 10000 * 64) * 64 * 64 * 32 / (dtr_lfacc/2^18 + 0x2000000)
* (Divide in 4 steps to prevent overflow.)
*/
Div = ((uint32_t)dtrlfacc + 0x2000000);
Q = (4800U * 10000U * 64U) / Div;
R = (4800U * 10000U * 64U) % Div;
R *= 64;
Q = (Q * 64) + (R / Div);
R = R % Div;
R *= 64;
Q = (Q * 64) + (R / Div);
R = R % Div;
R *= 32;
Q = (Q * 32) + (R / Div);
R = R % Div;
/* rounding and comparing with the standard symbol rate
* 8VSB: SymbolRateOffset[sps] = (10.762238 * 10^6 - Detected Symbol Rate)
*/
if (R <= (Div/2)) {
symbolRateOffset = (int32_t)(10762238 - Q);
}
else {
symbolRateOffset = (int32_t)(10762238 - (Q + 1));
}
/* Negative Value Check */
if (symbolRateOffset < 0) {
flgNegative = -1;
symbolRateOffset *= flgNegative;
}
/* SamplingOffset[ppm] = Symbol Rate Offset / 10.762238
* SamplingOffset * 100 = Symbol Rate Offset * 100 / 10.762238
* = Symbol Rate Offset * 10^8 / 10762238
* = Symbol Rate Offset * 500 * 500 * 200 / (10762238 / 2)
* (Divide in 4 steps to prevent overflow.)
*/
Div = 5381119;
Q = (uint32_t)symbolRateOffset / Div;
R = (uint32_t)symbolRateOffset % Div;
R *= 500;
Q = (Q * 500) + (R / Div);
R = R % Div;
R *= 500;
Q = (Q * 500) + (R / Div);
R = R % Div;
R *= 200;
Q = (Q * 200) + (R / Div);
R = R % Div;
if (R <= (Div/2)) {
*pPPM = flgNegative * (int32_t) Q;
} else {
*pPPM = flgNegative * (int32_t)(Q + 1);
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_SignalLevelData_ForUnlockOptimization (sony_demod_t * pDemod,
uint32_t * pSignalLevelData)
{
uint8_t data[3];
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_SignalLevelData_ForUnlockOptimization");
if ((!pDemod) || (!pSignalLevelData)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Set SLV-M Bank : 0x09 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x09) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* IFAGC Output
* slave Bank Addr Bit Name
* ---------------------------------------------------------------
* <SLV-M> 09h 68h [7:0] IDAGCA_IFLFACC[7:0]
* <SLV-M> 09h 69h [7:0] IDAGCA_IFLFACC[15:8]
* <SLV-M> 09h 6Ah [3:0] IDAGCA_IFLFACC[23:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x68, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pSignalLevelData = ((uint32_t) (data[2] & 0xFF) << 16) | ((uint32_t) (data[1] & 0xFF) << 8) | data[0];
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_demod_atsc_monitor_InternalDigitalAGCOut (sony_demod_t * pDemod,
uint32_t * pDigitalAGCOut)
{
uint8_t data[3];
SONY_TRACE_ENTER ("sony_demod_atsc_monitor_InternalDigitalAGCOut");
if ((!pDemod) || (!pDigitalAGCOut)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Software state check */
if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Set SLV-M Bank : 0x08 */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x08) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* Baseband AGC Control Value Monitor
* slave Bank Addr Bit Name
* ---------------------------------------------------------------
* <SLV-M> 08h 1Bh [7:0] IDBAGCA_GAIN[7:0]
* <SLV-M> 08h 1Ch [7:0] IDBAGCA_GAIN[15:8]
* <SLV-M> 08h 1Dh [3:0] IDBAGCA_GAIN[19:16]
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x1B, data, 3) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
*pDigitalAGCOut = ((data[2] & 0x0F) << 16) | (data[1] << 8) | data[0];
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t checkVQLock (sony_demod_t * pDemod)
{
uint8_t data = 0x00;
SONY_TRACE_ENTER ("checkVQLock");
if (!pDemod) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Set SLV-M Bank : 0x0D */
if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x00, 0x0D) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
/* DMD lock flag
* slave Bank Addr Bit Name Meaning
* -----------------------------------------------------------------------
* <SLV-M> 0Dh 86h [0] VQLOCK 0:UNLOCK, 1:LOCK
*/
if (pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVM, 0x86, &data, 1) != SONY_RESULT_OK) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C);
}
if (data & 0x01) {
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE);
}
}
+173
View File
@@ -0,0 +1,173 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
/**
@file sony_demod_atsc_monitor.h
This file provides the ATSC demodulator monitor interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_DEMOD_ATSC_MONITOR_H
#define SONY_DEMOD_ATSC_MONITOR_H
#include "../sony_demod.h"
/**
@brief Sync state monitor.
@param pDemod The demodulator instance.
@param pVQLockStat The demodulator lock condition.
- 0: DMD not locked.
- 1: DMD locked.
@param pAGCLockStat Indicates the AGC lock condition.
- 0: AGC not locked.
- 1: AGC locked.
@param pTSLockStat Indicates the TS lock condition.
- 0: TS not locked.
- 1: TS locked.
@param pUnlockDetected Indicates the early unlock condition.
- 0: No early unlock.
- 1: Early unlock.
@return SONY_RESULT_OK if successful and pVQLockStat, pAGCLockStat,
pTSLockStat, pUnlockDetected are valid.
*/
sony_result_t sony_demod_atsc_monitor_SyncStat (sony_demod_t * pDemod,
uint8_t * pVQLockStat,
uint8_t * pAGCLockStat,
uint8_t * pTSLockStat,
uint8_t * pUnlockDetected);
/**
@brief Monitor the IFAGC value.
Actual dB gain dependent on attached tuner.
@param pDemod The demodulator instance.
@param pIFAGCOut The IFAGC output register value. Range 0x000 - 0x3FFF. Unitless.
@return SONY_RESULT_OK if successful and pIFAGCOut valid.
*/
sony_result_t sony_demod_atsc_monitor_IFAGCOut (sony_demod_t * pDemod,
uint32_t * pIFAGCOut);
/**
@brief Monitors the detected carrier offset of the currently tuned channel.
To get the estimated center frequency of the current channel:
Freq_Est = Freq_Tune + pOffset;
This function will compensate for an inverting tuner architecture if the
demodulator has been configured accordingly using ::SONY_DEMOD_CONFIG_SPECTRUM_INV
config option for ::sony_demod_SetConfig.
@param pDemod The demodulator instance.
@param pOffset Carrier offset value (Hz).
@return SONY_RESULT_OK if successful and pOffset valid.
*/
sony_result_t sony_demod_atsc_monitor_CarrierOffset (sony_demod_t * pDemod,
int32_t * pOffset);
/**
@brief Monitor the Pre-RS BER.
@param pDemod The demodulator instance.
@param pBER Bit Error Rate value (Pre Reed-Solomon decoder) x 1e7.
@return SONY_RESULT_OK if successful and pBER valid.
*/
sony_result_t sony_demod_atsc_monitor_PreRSBER (sony_demod_t * pDemod,
uint32_t * pBER);
/**
@brief Monitor the Pre-RS SER (Symbol Error Rate).
@param pDemod The demodulator instance.
@param pSER Symbol Error Rate value (Pre Reed-Solomon decoder) x 1e7.
@return SONY_RESULT_OK if successful and pSER valid.
*/
sony_result_t sony_demod_atsc_monitor_PreRSSER (sony_demod_t * pDemod,
uint32_t * pSER);
/**
@brief Monitor the Post-RS WER (Word Error Rate).
@param pDemod The demodulator instance.
@param pWER Word Error Rate value (Post Reed-Solomon decoder) x 1e6.
@return SONY_RESULT_OK if successful and pWER valid.
*/
sony_result_t sony_demod_atsc_monitor_PostRSWER (sony_demod_t * pDemod,
uint32_t * pWER);
/**
@brief Monitor the Packet Error Detection.
This value will freeze when the packet error detected.
Another read transaction will refresh the value.
@param pDemod The demodulator instance.
@param pPacketErrorDetected The Packet Error Presence.
- 0: Packet Error absence.
- 1: Packet Error presence.
@return SONY_RESULT_OK if successful and pPacketErrorDetected valid.
*/
sony_result_t sony_demod_atsc_monitor_PacketError (sony_demod_t * pDemod,
uint8_t * pPacketErrorDetected);
/**
@brief Monitors the estimated SNR value.
@param pDemod The demodulator instance.
@param pSNR The estimated SNR in dBx1000.
@return SONY_RESULT_OK if successful and pSNR is valid.
*/
sony_result_t sony_demod_atsc_monitor_SNR (sony_demod_t * pDemod,
int32_t * pSNR);
/**
@brief Monitor the sampling frequency offset value.
@param pDemod The demodulator instance.
@param pPPM The sampling frequency offset in ppm x 100.
@return SONY_RESULT_OK if successful and pPPM is valid.
*/
sony_result_t sony_demod_atsc_monitor_SamplingOffset (sony_demod_t * pDemod,
int32_t * pPPM);
/**
@brief Monitor the signal level data to be used for ::SONY_DEMOD_CONFIG_ATSC_NO_SIGNAL_THRESH and
SONY_DEMOD_CONFIG_ATSC_SIGNAL_THRESH config option for ::sony_demod_SetConfig.
This function should not be used in the normal sequence,
but in the optimization sequence for early unlock detection.
@param pDemod The demodulator instance.
@param pSignalLevelData Indicates the Signal Level data for unlock optimization. Unitless.
@return SONY_RESULT_OK if successful and pSignalLevelData is valid.
*/
sony_result_t sony_demod_atsc_monitor_SignalLevelData_ForUnlockOptimization (sony_demod_t * pDemod,
uint32_t * pSignalLevelData);
/**
@brief Monitor the value of the Internal Digital AGC output.
@param pDemod The demodulator instance.
@param pDigitalAGCOut The value of the Internal Digital AGC output. (0x00000 - 0x7FFFF)
@return SONY_RESULT_OK if pDigitalAGCOut is valid.
*/
sony_result_t sony_demod_atsc_monitor_InternalDigitalAGCOut (sony_demod_t * pDemod,
uint32_t * pDigitalAGCOut);
#endif /* SONY_DEMOD_ATSC_MONITOR_H */
Binary file not shown.
+386
View File
@@ -0,0 +1,386 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/08/30
Modification ID : 902dae58eb5249e028ccc5d7f60bb66cca9b43a9
------------------------------------------------------------------------------*/
#include "sony_integ_atsc.h"
#include "sony_demod_atsc_monitor.h"
#include <stdio.h>
/*------------------------------------------------------------------------------
Static Function Prototypes
------------------------------------------------------------------------------*/
/**
@brief Waits for demodulator lock, polling ::sony_demod_atsc_monitor_SyncStat
at 10ms intervals. Called as part of the Tune process.
*/
static sony_result_t atsc_WaitVQLock (sony_integ_t * pInteg);
#define PR_DTUN printf
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_integ_atsc_Tune (sony_integ_t * pInteg,
sony_atsc_tune_param_t * pTuneParam)
{
sony_result_t result;
SONY_TRACE_ENTER ("sony_integ_atsc_Tune");
if ((!pInteg) || (!pTuneParam) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
//PR_TUN("dbg_pr [%s,%d] freq=%d\n",__FUNCTION__,__LINE__,pTuneParam->centerFreqKHz);
/* Tune the demodulator */
result = sony_demod_atsc_Tune (pInteg->pDemod, pTuneParam);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if ((pInteg->pTuner) && (pInteg->pTuner->TerrCableTune)) {
/* Enable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
PR_DTUN("dbg_pr [%s,%d] sony_demod_I2cRepeaterEnable 1\n",__FUNCTION__,__LINE__);
/* Tune the RF part */
result = pInteg->pTuner->TerrCableTune (pInteg->pTuner, pTuneParam->centerFreqKHz, SONY_DTV_SYSTEM_ATSC, SONY_DTV_BW_6_MHZ);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
PR_DTUN("dbg_pr [%s,%d] TerrCableTune \n",__FUNCTION__,__LINE__);
/* Disable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
PR_DTUN("dbg_pr [%s,%d] sony_demod_I2cRepeaterEnable 0\n",__FUNCTION__,__LINE__);
}
result = sony_demod_atsc_TuneEnd(pInteg->pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
PR_DTUN("dbg_pr [%s,%d] sony_demod_atsc_TuneEnd ,scanmode=%d \n",__FUNCTION__,__LINE__,pInteg->pDemod->scanMode);
if (!pInteg->pDemod->scanMode) {
result = sony_integ_atsc_WaitTSLock(pInteg);
if (result != SONY_RESULT_OK) {
PR_DTUN("dbg_pr [%s,%d] result=%d\n",__FUNCTION__,__LINE__,result); // 5
SONY_TRACE_RETURN (result);
}
} else {
result = atsc_WaitVQLock(pInteg);
if (result != SONY_RESULT_OK) {
PR_DTUN("dbg_pr [%s,%d] \n",__FUNCTION__,__LINE__);
SONY_TRACE_RETURN (result);
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc_Scan (sony_integ_t * pInteg,
sony_integ_atsc_scan_param_t * pScanParam,
sony_integ_atsc_scan_callback_t callBack)
{
sony_result_t result = SONY_RESULT_OK;
sony_integ_atsc_scan_result_t scanResult;
SONY_TRACE_ENTER ("sony_integ_atsc_Scan");
if ((!pInteg) || (!pScanParam) || (!callBack) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Ensure the scan parameters are valid. */
if (pScanParam->endFrequencyKHz < pScanParam->startFrequencyKHz) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pScanParam->stepFrequencyKHz == 0) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Set the start frequency */
scanResult.centerFreqKHz = pScanParam->startFrequencyKHz;
scanResult.tuneResult = SONY_RESULT_OK;
scanResult.tuneParam.centerFreqKHz = pScanParam->startFrequencyKHz;
/* Set scan mode enabled */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Scan routine */
while (scanResult.centerFreqKHz <= pScanParam->endFrequencyKHz) {
scanResult.tuneParam.centerFreqKHz = scanResult.centerFreqKHz;
scanResult.tuneResult = sony_integ_atsc_Tune(pInteg, &scanResult.tuneParam);
switch (scanResult.tuneResult) {
/* Channel found, callback to application */
case SONY_RESULT_OK:
callBack (pInteg, &scanResult, pScanParam);
break;
case SONY_RESULT_ERROR_UNLOCK:
case SONY_RESULT_ERROR_TIMEOUT:
/* Channel not found, callback to application for progress updates */
callBack (pInteg, &scanResult, pScanParam);
break;
default:
/* Serious error occurred -> cancel operation. */
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00);
SONY_TRACE_RETURN (scanResult.tuneResult);
}
scanResult.centerFreqKHz += pScanParam->stepFrequencyKHz;
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00);
SONY_TRACE_RETURN (result);
}
}
/* Clear scan mode */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (result);
}
sony_result_t sony_integ_atsc_WaitTSLock (sony_integ_t * pInteg)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_lock_result_t lock = SONY_DEMOD_LOCK_RESULT_NOTDETECT;
sony_stopwatch_t timer;
uint8_t continueWait = 1;
uint32_t elapsed = 0;
/*uint32_t waitTimeOut = 0;*/
SONY_TRACE_ENTER ("sony_integ_atsc_WaitTSLock");
if ((!pInteg) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Wait for TS lock */
result = sony_stopwatch_start (&timer);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
for (;;) {
result = sony_stopwatch_elapsed(&timer, &elapsed);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (elapsed >= SONY_ATSC_WAIT_TS_LOCK) {
continueWait = 0;
}
result = sony_demod_atsc_CheckTSLock (pInteg->pDemod, &lock);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
switch (lock) {
case SONY_DEMOD_LOCK_RESULT_LOCKED:
SONY_TRACE_RETURN (SONY_RESULT_OK);
case SONY_DEMOD_LOCK_RESULT_UNLOCKED:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK);
default:
/* continue waiting... */
break;
}
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (continueWait) {
result = sony_stopwatch_sleep (&timer, SONY_ATSC_WAIT_LOCK_INTERVAL);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
result = SONY_RESULT_ERROR_TIMEOUT;
break;
}
}
SONY_TRACE_RETURN (result);
}
sony_result_t sony_integ_atsc_monitor_RFLevel (sony_integ_t * pInteg,
int32_t * pRFLeveldB)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_integ_atsc_WaitTSLock");
if ((!pInteg) || (!pInteg->pDemod) || (!pRFLeveldB)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pInteg->pDemod->system != SONY_DTV_SYSTEM_ATSC) {
/* Not ATSC */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (!pInteg->pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_READ && pInteg->pTuner->ReadRFLevel) {
/* Enable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = pInteg->pTuner->ReadRFLevel (pInteg->pTuner, pRFLeveldB);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Disable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC
&& pInteg->pTuner->CalcRFLevelFromAGC) {
uint32_t ifAgc;
result = sony_demod_atsc_monitor_IFAGCOut (pInteg->pDemod, &ifAgc);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = pInteg->pTuner->CalcRFLevelFromAGC (pInteg->pTuner, ifAgc, pRFLeveldB);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
/* dBm * 100 -> dBm * 1000 */
*pRFLeveldB *= 10;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t atsc_WaitVQLock (sony_integ_t * pInteg)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_lock_result_t lock = SONY_DEMOD_LOCK_RESULT_NOTDETECT;
sony_stopwatch_t timer;
uint8_t continueWait = 1;
uint32_t elapsed = 0;
uint32_t waitTimeOut = 0;
SONY_TRACE_ENTER ("atsc_WaitVQLock");
if ((!pInteg) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in ACTIVE state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
waitTimeOut = SONY_ATSC_WAIT_DEMOD_LOCK;
/* Wait for demod lock */
result = sony_stopwatch_start (&timer);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
for (;;) {
result = sony_stopwatch_elapsed(&timer, &elapsed);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (elapsed >= waitTimeOut) {
continueWait = 0;
}
result = sony_demod_atsc_CheckDemodLock (pInteg->pDemod, &lock);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
switch (lock) {
case SONY_DEMOD_LOCK_RESULT_LOCKED:
SONY_TRACE_RETURN (SONY_RESULT_OK);
case SONY_DEMOD_LOCK_RESULT_UNLOCKED:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK);
default:
/* continue waiting... */
break;
}
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (continueWait) {
result = sony_stopwatch_sleep (&timer, SONY_ATSC_WAIT_LOCK_INTERVAL);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
else {
result = SONY_RESULT_ERROR_TIMEOUT;
break;
}
}
SONY_TRACE_RETURN (result);
}
+159
View File
@@ -0,0 +1,159 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
/**
@file sony_integ_atsc.h
This file provides the integration layer interface for ATSC
specific demodulator functions.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_INTEG_ATSC_H
#define SONY_INTEG_ATSC_H
#include "../sony_integ.h"
#include "sony_demod_atsc.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_ATSC_WAIT_DEMOD_LOCK 1200 /**< 1.2s timeout for wait demodulator lock process for ATSC channels */
#define SONY_ATSC_WAIT_TS_LOCK 1200 /**< 1.2s timeout for wait TS lock process for ATSC channels */
#define SONY_ATSC_WAIT_LOCK_INTERVAL 10 /**< 10ms polling interval for demodulator and TS lock functions */
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief The parameters used for ATSC scanning.
*/
typedef struct sony_integ_atsc_scan_param_t {
/**
@brief The start frequency in kHz for scanning. Ensure that this is
aligned with the channel raster.
*/
uint32_t startFrequencyKHz;
/**
@brief The end frequency in kHz for scanning.
*/
uint32_t endFrequencyKHz;
/**
@brief The step frequency in kHz for scanning.
*/
uint32_t stepFrequencyKHz;
} sony_integ_atsc_scan_param_t;
/**
@brief The structure used to return a channel located or progress update
as part of a ATSC or combined scan.
*/
typedef struct sony_integ_atsc_scan_result_t {
/**
@brief Indicates the current frequency just attempted for the scan.
This would primarily be used to calculate scan progress from the scan parameters.
*/
uint32_t centerFreqKHz;
/**
@brief Indicates if the tune result at the current frequency.
SONY_RESULT_OK means that a channel has been locked
and one of the tuneParam structures contain the channel information.
*/
sony_result_t tuneResult;
/**
@brief The tune params for a located ATSC channel.
*/
sony_atsc_tune_param_t tuneParam;
} sony_integ_atsc_scan_result_t;
/*------------------------------------------------------------------------------
Function Pointers
------------------------------------------------------------------------------*/
/**
@brief Callback function that is called for every attempted frequency during a scan.
For successful channel results the function is called after
demodulator lock but before TS lock is achieved (ATSC : VQ Lock).
@param pInteg The driver instance.
@param pResult The current scan result.
@param pScanParam The current scan parameters.
*/
typedef void (*sony_integ_atsc_scan_callback_t) (sony_integ_t * pInteg,
sony_integ_atsc_scan_result_t * pResult,
sony_integ_atsc_scan_param_t * pScanParam);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Performs acquisition to a ATSC channel.
Blocks the calling thread until the TS has locked or has timed out.
Use ::sony_integ_Cancel to cancel the operation at any time.
@param pInteg The driver instance.
@param pTuneParam The parameters required for the tune.
@return SONY_RESULT_OK if tuned successfully to the channel.
*/
sony_result_t sony_integ_atsc_Tune (sony_integ_t * pInteg,
sony_atsc_tune_param_t * pTuneParam);
/**
@brief Performs a scan over the spectrum specified.
Blocks the calling thread while scanning. Use ::sony_integ_Cancel to cancel
the operation at any time.
@param pInteg The driver instance.
@param pScanParam The scan parameters.
@param callBack User registered call-back to receive scan progress information and
notification of found channels. The call back is called for every attempted
frequency during a scan.
@return SONY_RESULT_OK if scan completed successfully.
*/
sony_result_t sony_integ_atsc_Scan (sony_integ_t * pInteg,
sony_integ_atsc_scan_param_t * pScanParam,
sony_integ_atsc_scan_callback_t callBack);
/**
@brief Polls the demodulator waiting for TS lock at 10ms intervals up to the
demodulation mode dependent timeout.
@param pInteg The driver instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_integ_atsc_WaitTSLock (sony_integ_t * pInteg);
/**
@brief This function returns the estimated RF level based on either the demodulator IFAGC
level or a tuner internal RSSI monitor.
If any compensation for external hardware
such as, LNA, attenuators is required, then the user should make adjustment in the
corresponding function.
@param pInteg The driver instance
@param pRFLeveldB The RF Level estimation in dB * 1000
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_integ_atsc_monitor_RFLevel (sony_integ_t * pInteg,
int32_t * pRFLeveldB);
#endif /* SONY_INTEG_ATSC_H */
Binary file not shown.
+756
View File
@@ -0,0 +1,756 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/12/13
Modification ID : e402a4dcb0e51a00c34b174334c082c1211eebf1
------------------------------------------------------------------------------*/
#include "../sony_integ.h"
#include "sony_integ_atsc3.h"
#include "../sony_demod.h"
#include "sony_demod_atsc3_monitor.h"
static sony_result_t atsc3_WaitDemodLock (sony_integ_t * pInteg);
static sony_result_t atsc3_WaitCWTracking (sony_integ_t * pInteg);
//#define TUN_PR printf
#define TUN_PR(...)
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_integ_atsc3_Tune (sony_integ_t * pInteg,
sony_atsc3_tune_param_t * pTuneParam)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_integ_atsc3_Tune");
if ((!pInteg) || (!pTuneParam) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Check bandwidth validity */
if ((pTuneParam->bandwidth != SONY_DTV_BW_6_MHZ) && (pTuneParam->bandwidth != SONY_DTV_BW_7_MHZ) &&
(pTuneParam->bandwidth != SONY_DTV_BW_8_MHZ)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
result = sony_demod_atsc3_AutoDetectSeq_Init (pInteg->pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Configure for manual PLP selection. */
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
if ((pInteg->pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN)
|| (pInteg->pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB)) {
/* PLP configuration for channel bonding case */
result = sony_demod_atsc3_chbond_SetPLPConfig (pInteg->pDemod, pTuneParam->plpIDNum, pTuneParam->plpID, pTuneParam->plpBond);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else
#endif /* SONY_DEMOD_SUPPORT_ATSC3_CHBOND */
{
result = sony_demod_atsc3_SetPLPConfig (pInteg->pDemod, pTuneParam->plpIDNum, pTuneParam->plpID);
TUN_PR("[%s,%d] sony_demod_atsc3_SetPLPConfig result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* Tune the demodulator */
result = sony_demod_atsc3_Tune (pInteg->pDemod, pTuneParam);
TUN_PR("[%s,%d] tune demod result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if ((pInteg->pTuner) && (pInteg->pTuner->TerrCableTune)) {
/* Enable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01);
TUN_PR("[%s,%d] Enable the I2C repeater result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Tune the RF part */
result = pInteg->pTuner->TerrCableTune (pInteg->pTuner, pTuneParam->centerFreqKHz, SONY_DTV_SYSTEM_ATSC3, pTuneParam->bandwidth);
TUN_PR("[%s,%d] Tune the RF part result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Disable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00);
printf("[%s,%d] Tune the RF part result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* Reset the demod to enable acquisition */
result = sony_demod_TuneEnd (pInteg->pDemod);
TUN_PR("[%s,%d] demod tunend. result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = atsc3_WaitDemodLock (pInteg);
TUN_PR("[%s,%d] wait demod lock . result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = atsc3_WaitCWTracking (pInteg);
TUN_PR("[%s,%d] wait CW tracking . result=%d pInteg->pDemod->scanMode=%d\n",__FUNCTION__,__LINE__,result,pInteg->pDemod->scanMode);
if ((result != SONY_RESULT_OK) && (result != SONY_RESULT_ERROR_TIMEOUT)) {
/* Even if timeout error occurred and failed to configure CW tracking,
should continue without error. Demodulator may lock target ALPs after that. */
SONY_TRACE_RETURN (result);
}
//------------------------------------------
if (!pInteg->pDemod->scanMode) {
result = sony_integ_atsc3_WaitALPLock (pInteg);
TUN_PR("[%s,%d] wait alp lock . result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
TUN_PR("[%s,%d]\n",__FUNCTION__,__LINE__);
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc3_EASTune (sony_integ_t * pInteg,
sony_atsc3_tune_param_t * pTuneParam)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_integ_atsc3_EASTune");
if ((!pInteg) || (!pTuneParam) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Check bandwidth validity */
if ((pTuneParam->bandwidth != SONY_DTV_BW_6_MHZ) && (pTuneParam->bandwidth != SONY_DTV_BW_7_MHZ) &&
(pTuneParam->bandwidth != SONY_DTV_BW_8_MHZ)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
result = sony_demod_atsc3_AutoDetectSeq_Init (pInteg->pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Tune the demodulator */
result = sony_demod_atsc3_EASTune (pInteg->pDemod, pTuneParam);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if ((pInteg->pTuner) && (pInteg->pTuner->TerrCableTune)) {
/* Enable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Tune the RF part */
result = pInteg->pTuner->TerrCableTune (pInteg->pTuner, pTuneParam->centerFreqKHz, SONY_DTV_SYSTEM_ATSC3, pTuneParam->bandwidth);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Disable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
/* Reset the demod to enable acquisition */
result = sony_demod_atsc3_EASTuneEnd (pInteg->pDemod);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = atsc3_WaitDemodLock (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = atsc3_WaitCWTracking (pInteg);
if ((result != SONY_RESULT_OK) && (result != SONY_RESULT_ERROR_TIMEOUT)) {
/* Even if timeout error occurred and failed to configure CW tracking,
should continue without error. Demodulator may lock target ALPs after that. */
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc3_Scan (sony_integ_t * pInteg,
sony_integ_atsc3_scan_param_t * pScanParam,
sony_integ_atsc3_scan_callback_t callBack)
{
sony_result_t result = SONY_RESULT_OK;
sony_integ_atsc3_scan_result_t scanResult;
SONY_TRACE_ENTER ("sony_integ_atsc3_Scan");
if ((!pInteg) || (!pScanParam) || (!callBack) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Ensure the scan parameters are valid. */
if (pScanParam->endFrequencyKHz < pScanParam->startFrequencyKHz) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pScanParam->stepFrequencyKHz == 0) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Check bandwidth validity */
if ((pScanParam->bandwidth != SONY_DTV_BW_6_MHZ) && (pScanParam->bandwidth != SONY_DTV_BW_7_MHZ) &&
(pScanParam->bandwidth != SONY_DTV_BW_8_MHZ)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
/* Set the start frequency and other parameters. */
scanResult.centerFreqKHz = pScanParam->startFrequencyKHz;
scanResult.tuneResult = SONY_RESULT_OK;
scanResult.tuneParam.centerFreqKHz = pScanParam->startFrequencyKHz;
scanResult.tuneParam.bandwidth = pScanParam->bandwidth;
scanResult.tuneParam.plpIDNum = 1;
scanResult.tuneParam.plpID[0] = 0;
scanResult.tuneParam.plpID[1] = 0;
scanResult.tuneParam.plpID[2] = 0;
scanResult.tuneParam.plpID[3] = 0;
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
scanResult.tuneParam.plpBond[0] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[1] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[2] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[3] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
#endif
/* Set scan mode enabled */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
while (scanResult.centerFreqKHz <= pScanParam->endFrequencyKHz) {
scanResult.tuneParam.centerFreqKHz = scanResult.centerFreqKHz;
scanResult.tuneResult = sony_integ_atsc3_Tune(pInteg, &scanResult.tuneParam);
switch (scanResult.tuneResult) {
case SONY_RESULT_OK:
/* Channel found, callback to application */
callBack (pInteg, &scanResult, pScanParam);
printf("sony_integ_atsc3_Tune SONY_RESULT_OK\n");
break;
case SONY_RESULT_ERROR_UNLOCK:
case SONY_RESULT_ERROR_TIMEOUT:
/* Channel not found, callback to application for progress updates */
callBack (pInteg, &scanResult, pScanParam);
printf("sony_integ_atsc3_Tune SONY_RESULT_ERROR %d\n\n", scanResult.tuneResult);
break;
default:
/* Serious error occurred -> cancel operation. */
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
SONY_TRACE_RETURN (scanResult.tuneResult);
}
scanResult.centerFreqKHz += pScanParam->stepFrequencyKHz;
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
printf("sony_integ_CheckCancellation SONY_RESULT_ERR %d\n", result);
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
SONY_TRACE_RETURN (result);
}
}
/* Clear scan mode */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc3_Scan_plpnum (sony_integ_t * pInteg,
sony_integ_atsc3_scan_param_t * pScanParam,
sony_integ_atsc3_scan_callback_t callBack,
uint8_t plpnum, uint8_t plpid0,uint8_t plpid1,
uint8_t plpid2,uint8_t plpid3)
{
sony_result_t result = SONY_RESULT_OK;
sony_integ_atsc3_scan_result_t scanResult;
SONY_TRACE_ENTER ("sony_integ_atsc3_Scan");
if ((!pInteg) || (!pScanParam) || (!callBack) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) {
/* This api is accepted in Sleep and Active states only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Ensure the scan parameters are valid. */
if (pScanParam->endFrequencyKHz < pScanParam->startFrequencyKHz) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pScanParam->stepFrequencyKHz == 0) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Check bandwidth validity */
if ((pScanParam->bandwidth != SONY_DTV_BW_6_MHZ) && (pScanParam->bandwidth != SONY_DTV_BW_7_MHZ) &&
(pScanParam->bandwidth != SONY_DTV_BW_8_MHZ)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
/* Set the start frequency and other parameters. */
scanResult.centerFreqKHz = pScanParam->startFrequencyKHz;
scanResult.tuneResult = SONY_RESULT_OK;
scanResult.tuneParam.centerFreqKHz = pScanParam->startFrequencyKHz;
scanResult.tuneParam.bandwidth = pScanParam->bandwidth;
scanResult.tuneParam.plpIDNum = plpnum;
scanResult.tuneParam.plpID[0] = plpid0;
scanResult.tuneParam.plpID[1] = plpid1;
scanResult.tuneParam.plpID[2] = plpid2;
scanResult.tuneParam.plpID[3] = plpid3;
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
scanResult.tuneParam.plpBond[0] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[1] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[2] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
scanResult.tuneParam.plpBond[3] = SONY_DEMOD_ATSC3_CHBOND_PLP_BOND_ENABLE;
#endif
/* Set scan mode enabled */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
printf ("enable scan ok\n");
while (scanResult.centerFreqKHz <= pScanParam->endFrequencyKHz) {
scanResult.tuneParam.centerFreqKHz = scanResult.centerFreqKHz;
printf(" scanResult.centerFreqKHz=%d, plpnum=%d \n",scanResult.centerFreqKHz,
scanResult.tuneParam.plpIDNum);
scanResult.tuneResult = sony_integ_atsc3_Tune(pInteg, &scanResult.tuneParam);
switch (scanResult.tuneResult) {
case SONY_RESULT_OK:
printf("scanResult :centerFreqKHz=%d, plpnum=%d %d,%d,%d,%d\n",scanResult.centerFreqKHz,
scanResult.tuneParam.plpIDNum,
scanResult.tuneParam.plpID[0],
scanResult.tuneParam.plpID[1],
scanResult.tuneParam.plpID[2],
scanResult.tuneParam.plpID[3]);
/* Channel found, callback to application */
callBack (pInteg, &scanResult, pScanParam);
printf("callBack done\n");
break;
case SONY_RESULT_ERROR_UNLOCK:
case SONY_RESULT_ERROR_TIMEOUT:
/* Channel not found, callback to application for progress updates */
callBack (pInteg, &scanResult, pScanParam);
break;
default:
/* Serious error occurred -> cancel operation. */
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
SONY_TRACE_RETURN (scanResult.tuneResult);
}
scanResult.centerFreqKHz += pScanParam->stepFrequencyKHz;
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
printf ("result=%d\n", result);
if (result != SONY_RESULT_OK) {
sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
SONY_TRACE_RETURN (result);
}
}
printf ("disable scan\n");
/* Clear scan mode */
result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC3, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc3_SwitchPLP (sony_integ_t * pInteg,
uint8_t plpIDNum,
uint8_t plpID[4])
{
sony_result_t result;
SONY_TRACE_ENTER ("sony_integ_atsc3_SwitchPLP");
if ((!pInteg) || (!pInteg->pDemod) || (plpIDNum > 4)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pInteg->pDemod->system != SONY_DTV_SYSTEM_ATSC3) {
/* Not ATSC 3.0 */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pInteg->pDemod->atsc3EasState == SONY_DEMOD_ATSC3_EAS_STATE_EAS) {
/* In EAS mode, ALP is not output */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
#ifdef SONY_DEMOD_SUPPORT_ATSC3_CHBOND
if ((pInteg->pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_MAIN)
|| (pInteg->pDemod->chbondConfig == SONY_DEMOD_CHBOND_CONFIG_ATSC3_SUB)) {
/* Unavailable for channel bonding */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
#endif /* SONY_DEMOD_SUPPORT_ATSC3_CHBOND */
result = sony_demod_atsc3_SetPLPConfig (pInteg->pDemod, plpIDNum, plpID);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = sony_integ_atsc3_WaitALPLock (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_integ_atsc3_WaitALPLock (sony_integ_t * pInteg)
{
sony_result_t result = SONY_RESULT_OK;
sony_stopwatch_t timer;
uint8_t continueWait = 1;
uint32_t elapsed = 0;
sony_demod_lock_result_t lock;
uint8_t sync_status = 0;
uint8_t alp_lock_all = 0;
SONY_TRACE_ENTER ("sony_integ_atsc3_WaitALPLock");
if ((!pInteg) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
TUN_PR("[%s,%d] \n",__FUNCTION__,__LINE__);
TUN_PR("[%s,%d] pInteg->pDemod->state=%d \n",__FUNCTION__,__LINE__,pInteg->pDemod->state );
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
result = sony_stopwatch_start (&timer);
TUN_PR("[%s,%d] sony_stopwatch_start result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
int count=0;
for (;;) {
count++;
result = sony_stopwatch_elapsed(&timer, &elapsed);
TUN_PR("[%s,%d] (cnt=%d elapsed=%d) sony_stopwatch_elapsed result=%d\n",__FUNCTION__,__LINE__,count,elapsed,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Check for timeout condition */
if (elapsed >= SONY_ATSC3_WAIT_ALP_LOCK) {
continueWait = 0;
}
result = sony_demod_atsc3_CheckALPLock (pInteg->pDemod, &lock, &sync_status, &alp_lock_all);
TUN_PR("[%s,%d] sony_demod_atsc3_CheckALPLock result=%d\n",__FUNCTION__,__LINE__,result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
switch (lock) {
case SONY_DEMOD_LOCK_RESULT_LOCKED:
SONY_TRACE_RETURN (SONY_RESULT_OK);
case SONY_DEMOD_LOCK_RESULT_UNLOCKED:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK);
default:
/* continue waiting... */
break;
}
TUN_PR("[%s,%d] lock=%d\n\n",__FUNCTION__,__LINE__,lock);
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (continueWait) {
result = sony_stopwatch_sleep (&timer, SONY_ATSC3_WAIT_LOCK_INTERVAL);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
else {
result = SONY_RESULT_ERROR_TIMEOUT;
break;
}
}
SONY_TRACE_RETURN (result);
}
sony_result_t sony_integ_atsc3_monitor_RFLevel (sony_integ_t * pInteg,
int32_t * pRFLeveldB)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_integ_atsc3_monitor_RFLevel");
if ((!pInteg) || (!pInteg->pDemod) || (!pRFLeveldB)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (pInteg->pDemod->system != SONY_DTV_SYSTEM_ATSC3) {
/* Not ATSC 3.0 */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
if (!pInteg->pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_READ && pInteg->pTuner->ReadRFLevel) {
/* Enable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = pInteg->pTuner->ReadRFLevel (pInteg->pTuner, pRFLeveldB);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Disable the I2C repeater */
result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC
&& pInteg->pTuner->CalcRFLevelFromAGC) {
uint32_t ifAgc;
result = sony_demod_atsc3_monitor_IFAGCOut (pInteg->pDemod, &ifAgc);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
result = pInteg->pTuner->CalcRFLevelFromAGC (pInteg->pTuner, ifAgc, pRFLeveldB);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
/* dBm * 100 -> dBm * 1000 */
*pRFLeveldB *= 10;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t atsc3_WaitDemodLock (sony_integ_t * pInteg)
{
sony_result_t result = SONY_RESULT_OK;
sony_demod_lock_result_t lock = SONY_DEMOD_LOCK_RESULT_NOTDETECT;
uint16_t timeout = 0;
sony_stopwatch_t timer;
uint8_t continueWait = 1;
uint32_t elapsed = 0;
SONY_TRACE_ENTER ("atsc3_WaitDemodLock");
if ((!pInteg) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Wait for demod lock */
result = sony_stopwatch_start (&timer);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
timeout = SONY_ATSC3_WAIT_DEMOD_LOCK;
for (;;) {
result = sony_stopwatch_elapsed (&timer, &elapsed);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (elapsed >= timeout) {
continueWait = 0;
}
result = sony_demod_atsc3_CheckDemodLock (pInteg->pDemod, &lock);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
switch (lock) {
case SONY_DEMOD_LOCK_RESULT_LOCKED:
SONY_TRACE_RETURN (SONY_RESULT_OK);
case SONY_DEMOD_LOCK_RESULT_UNLOCKED:
result = sony_demod_atsc3_AutoDetectSeq_UnlockCase (pInteg->pDemod, &continueWait);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (!continueWait) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK);
}
/* continue waiting... */
break;
default:
/* continue waiting... */
break;
}
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (continueWait) {
result = sony_stopwatch_sleep (&timer, SONY_ATSC3_WAIT_LOCK_INTERVAL);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
result = SONY_RESULT_ERROR_TIMEOUT;
break;
}
}
SONY_TRACE_RETURN (result);
}
static sony_result_t atsc3_WaitCWTracking (sony_integ_t * pInteg)
{
sony_result_t result = SONY_RESULT_OK;
uint16_t timeout = 0;
sony_stopwatch_t timer;
uint8_t completed = 1;
uint8_t continueWait = 1;
uint32_t elapsed = 0;
SONY_TRACE_ENTER ("atsc3_WaitCWTracking");
if ((!pInteg) || (!pInteg->pDemod)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
/* This api is accepted in Active state only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/* Wait for CW Tracking Completion */
result = sony_stopwatch_start (&timer);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
timeout = SONY_ATSC3_WAIT_CW_TRACKING_TIMEOUT;
for (;;) {
result = sony_stopwatch_elapsed (&timer, &elapsed);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (elapsed >= timeout) {
continueWait = 0;
}
result = sony_demod_atsc3_AutoDetectSeq_SetCWTracking (pInteg->pDemod, &completed);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (completed) {
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
/* Check cancellation. */
result = sony_integ_CheckCancellation (pInteg);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
if (continueWait) {
result = sony_stopwatch_sleep (&timer, SONY_ATSC3_WAIT_LOCK_INTERVAL);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
result = SONY_RESULT_ERROR_TIMEOUT;
break;
}
}
SONY_TRACE_RETURN (result);
}
+207
View File
@@ -0,0 +1,207 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/08/30
Modification ID : 902dae58eb5249e028ccc5d7f60bb66cca9b43a9
------------------------------------------------------------------------------*/
/**
@file sony_integ_atsc3.h
This file provides the integration layer interface for ATSC 3.0
specific demodulator functions.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_INTEG_ATSC3_H
#define SONY_INTEG_ATSC3_H
#include "../sony_demod.h"
#include "../sony_integ.h"
#include "sony_demod_atsc3.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_ATSC3_WAIT_DEMOD_LOCK 3500 /**< 3.5s timeout for wait demodulator lock process for ATSC 3.0 channels */
#define SONY_ATSC3_WAIT_ALP_LOCK 5000//4000 //1500 /**< 1.5s timeout for wait ALP lock process for ATSC 3.0 channels */
#define SONY_ATSC3_WAIT_CW_TRACKING_TIMEOUT 300 /**< 300msec timeout for wait CW Tracking Completion */
#define SONY_ATSC3_WAIT_LOCK_INTERVAL 10 /**< 10ms polling interval for demodulator, ALP lock and CW Tracking functions */
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief The parameters used for ATSC 3.0 scanning.
*/
typedef struct sony_integ_atsc3_scan_param_t {
/**
@brief The start frequency in kHz for scanning.
Ensure that this is aligned with the channel raster.
*/
uint32_t startFrequencyKHz;
/**
@brief The end frequency in kHz for scanning.
*/
uint32_t endFrequencyKHz;
/**
@brief The step frequency in kHz for scanning.
*/
uint32_t stepFrequencyKHz;
/**
@brief The bandwidth to use for tuning during the scan
*/
sony_dtv_bandwidth_t bandwidth;
} sony_integ_atsc3_scan_param_t;
/**
@brief The structure used to return a channel located or progress update
as part of a ATSC 3.0 scan.
*/
typedef struct sony_integ_atsc3_scan_result_t {
/**
@brief Indicates the current frequency just attempted for the scan.
This would primarily be used to calculate scan progress from the scan parameters.
*/
uint32_t centerFreqKHz;
/**
@brief Indicates if the tune result at the current frequency.
SONY_RESULT_OK means that a channel has been locked.
*/
sony_result_t tuneResult;
/**
@brief The tune params for a located ATSC 3.0 channel.
Note that plpIDNum and plpID[] are temporary value.
*/
sony_atsc3_tune_param_t tuneParam;
} sony_integ_atsc3_scan_result_t;
/*------------------------------------------------------------------------------
Function Pointers
------------------------------------------------------------------------------*/
/**
@brief Callback function that is called for every attempted frequency during a scan.
For successful channel results the function is called after
demodulator lock but before ALP lock is achieved.
@param pInteg The driver instance.
@param pResult The current scan result.
@param pScanParam The current scan parameters.
*/
typedef void (*sony_integ_atsc3_scan_callback_t) (sony_integ_t * pInteg,
sony_integ_atsc3_scan_result_t * pResult,
sony_integ_atsc3_scan_param_t * pScanParam);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Performs acquisition to a ATSC 3.0 channel.
Blocks the calling thread until the ALP has locked or has timed out.
Use ::sony_integ_Cancel to cancel the operation at any time.
@param pInteg The driver instance.
@param pTuneParam The parameters required for the tune.
@return SONY_RESULT_OK if tuned successfully to the channel.
*/
sony_result_t sony_integ_atsc3_Tune (sony_integ_t * pInteg,
sony_atsc3_tune_param_t * pTuneParam);
/**
@brief Performs acquisition to a ATSC 3.0 channel in EAS mode.
EAS (Emergency Alert System) mode is used for waiting EAS flags, without ALP stream output.
PLP related settings in ::sony_atsc3_tune_param_t are ignored.
Several monitor APIs (SNR, BER, FER, L1 information ...) cannot work in EAS mode.
Blocks the calling thread until the Demod has locked or has timed out.
Use ::sony_integ_Cancel to cancel the operation at any time.
@param pInteg The driver instance.
@param pTuneParam The parameters required for the tune.
@return SONY_RESULT_OK if tuned successfully to the channel.
*/
sony_result_t sony_integ_atsc3_EASTune (sony_integ_t * pInteg,
sony_atsc3_tune_param_t * pTuneParam);
/**
@brief Performs a scan over the spectrum specified.
Perform a ATSC 3.0 system scan for ATSC 3.0 channels.
Blocks the calling thread while scanning. Use ::sony_integ_Cancel to cancel
the operation at any time.
@param pInteg The driver instance.
@param pScanParam The scan parameters.
@param callBack User registered call-back to receive scan progress information and
notification of found channels. The call back is called for every attempted
frequency during a scan.
@return SONY_RESULT_OK if scan completed successfully.
*/
sony_result_t sony_integ_atsc3_Scan (sony_integ_t * pInteg,
sony_integ_atsc3_scan_param_t * pScanParam,
sony_integ_atsc3_scan_callback_t callBack);
sony_result_t sony_integ_atsc3_Scan_plpnum (sony_integ_t * pInteg,
sony_integ_atsc3_scan_param_t * pScanParam,
sony_integ_atsc3_scan_callback_t callBack,
uint8_t plpnum, uint8_t plpid0,uint8_t plpid1,
uint8_t plpid2,uint8_t plpid3);
/**
@brief Change the PLP on currently tuned channel.
Change the PLP configuration of the demodulator and wait completion (ALP lock).
@param pInteg The driver instance
@param plpIDNum Number of valid PLP ID in plpID[]. (1 - 4)
@param plpID The pointer of PLP ID 4 length array to set.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_integ_atsc3_SwitchPLP (sony_integ_t * pInteg,
uint8_t plpIDNum,
uint8_t plpID[4]);
/**
@brief Polls the demodulator waiting for ALP lock at 10ms intervals.
@param pInteg The driver instance
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_integ_atsc3_WaitALPLock (sony_integ_t * pInteg);
/**
@brief This function returns the estimated RF level based on either the demodulator IFAGC
level or a tuner internal RSSI monitor.
If any compensation for external hardware
such as, LNA, attenuators is required, then the user should make adjustment in the
corresponding function.
@param pInteg The driver instance
@param pRFLeveldB The RF Level estimation in dB * 1000
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_integ_atsc3_monitor_RFLevel (sony_integ_t * pInteg,
int32_t * pRFLeveldB);
#endif /* SONY_INTEG_ATSC3_H */
Binary file not shown.