phantom_api.c
来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 1,923 行 · 第 1/5 页
C
1,923 行
/* phantom_api.c */
/*+++ *******************************************************************\
*
* Abstract:
*
* Phantom API functions
*
* Created: 3/30/2004
*
* Author: Amarnath Puttur
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2004 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
#include <stdlib.h> /* ANSI Standard */
#include <ctype.h> /* ANSI Standard */
#include <string.h> /* ANSI Standard */
#include "phantom.h" /* phantom include files: ordered */
#include "phantom_defs.h" /* Defines */
#include "cs_assert.h"
extern const unsigned char phantom_xprog[]; /* program image */
extern const unsigned long phantom_xprog_length;
/*******************************************************************************************************/
/*******************************************************************************************************
* PHANTOM_InitEnvironment()
* function to initialize a PHANTOM_NIM* passed by application
*******************************************************************************************************/
BOOL
PHANTOM_InitEnvironment(PHANTOM_NIM* p_nim, /* nim pointer used by all API functions */
unsigned long demod_handle, /* demod handle to be associated with this PHANTOM_NIM (user-specific) */
PHANTOM_MULTI_WRITE_SB SBMultiWrite, /* pointer to user-supplied low-level multiple write I/O function */
PHANTOM_WRITE_SB SBwrite, /* pointer to user-supplied low-level write I/O function */
PHANTOM_READ_SB SBread, /* pointer to user-supplied low-level read I/O function */
unsigned long crystal_frequency, /* crystal (,freq of) attached to PHANTOM_NIM card */
PHANTOM_TUNER_REF_CLOCKOUT_DIV tuner_ref_clkout_div, /* post divide ref clock out to demod. */
unsigned char pll_multiplier, /* PLL multiplier 0xF2 [5:0] */
PHANTOM_MPEG_OUT* p_mpeg) /* default MPEG settings */
{
int index;
PHANTOM_SW_DOWNLOAD download;
PHANTOM_DEMOD demod;
unsigned long ref_clk_divider;
/**************************************************************************
* Sanity checks. *
**************************************************************************/
if (p_nim == (PHANTOM_NIM*)0)
{
return(False);
}
if (PHANTOM_DRIVER_ValidNim(p_nim) == True)
{
/* invalid p_nim or already allocated */
PHANTOM_DBG_SET_ERROR(PHANTOM_NIM_OPENED);
return(False);
}
if (p_mpeg == 0)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_INIT_MPEG);
return(False);
}
/* flag bad sbread/sbwrite functions as errors */
/* It's O.K. if SBMultiWrite is 0, SW download will use SBWrite */
if (SBwrite == 0 || SBread == 0)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_SBIO_NULL);
return(False);
}
#if PHANTOM_INCLUDE_DEBUG
PHANTOM_DBG_Init(); // Initialize the debug module
#endif /* PHANTOM_INCLUDE_DEBUG */
/**************************************************************************
* Initialize PHANTOM_NIM structure. *
**************************************************************************/
/* clear the entire p_nim struct */
memset (p_nim, 0, sizeof(PHANTOM_NIM));
/* test for valid crystal */
if (crystal_frequency < (unsigned long)(PHANTOM_FREQ_XTAL_LOW * PHANTOM_ONEMILLION) ||
crystal_frequency > (unsigned long)(PHANTOM_FREQ_XTAL_HIGH * PHANTOM_ONEMILLION))
{
/* xtal presented at init...() is out-of-bounds */
PHANTOM_DBG_SET_ERROR(PHANTOM_INIT_XTAL);
return(False);
}
p_nim->demod_ref_clock = crystal_frequency / PHANTOM_REF_CLOCK_DIVIDER;
p_nim->crystal_freq = crystal_frequency;
p_nim->symbol_rate = PHANTOM_NIM_DEFAULT_SYMB;
p_nim->prev_acqstate = PHANTOM_ACQ_OFF;
/* place the new p_nim into the p_nim_list */
for (index = 0; index < PHANTOM_MAX_NIMS; index++)
{
if (phantom_nim_list.nim[index] == 0)
{
phantom_nim_list.nim[index] = p_nim;
break;
}
}
/* save the demod handle, i/o function pointers */
p_nim->demod_handle = demod_handle;
p_nim->SBWrite = SBwrite;
p_nim->SBRead = SBread;
p_nim->SBMultiWrite = SBMultiWrite;
/**************************************************************************
* Init hardware. *
**************************************************************************/
p_nim->pll_sdiv = pll_multiplier;
if (PHANTOM_DRIVER_HWInit(p_nim) == False)
{
CSTRACE(ERROR_LEVEL,"PHANTOM_DRIVER_HWInit error\r\n");
return (False);
}
/**************************************************************************
* Download firmware images. *
**************************************************************************/
/* Initialize the download parameters */
download.p_code = (unsigned char*)phantom_xprog;
download.code_length = phantom_xprog_length;
if (PHANTOM_DownloadFirmware(p_nim, &download) == False)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_FIRMWARE_DOWNLOAD_FAILED);
CSTRACE(ERROR_LEVEL,"PHANTOM_DownloadFirmware error\r\n");
return(False);
}
/********************************************************************************
* Pass the inverse VCO freq. to the firmware. Issue this LLF before tuner init.*
********************************************************************************/
if (PHANTOM_DRIVER_SetVCOFrequency(p_nim) == False)
{
CSTRACE(ERROR_LEVEL,"PHANTOM_DRIVER_SetVCOFrequency error\r\n");
return(False);
}
/**************************************************************************
* Initialize the Tuner immediately after the download *
**************************************************************************/
p_nim->tuner_gain_thresh = -50; /* default */
if (PHANTOM_DRIVER_InitTuner(p_nim, tuner_ref_clkout_div) == False)
{
CSTRACE(ERROR_LEVEL,"PHANTOM_DRIVER_InitTuner error\r\n");
return (False);
}
/* Adjust the post divider in the demod to match the tuner's divider setting */
ref_clk_divider = PHANTOM_REF_CLK_DIV2; /* demod divides by 2 */
if (p_nim->tuner_ref_clkout_div == PHANTOM_TUNER_REF_CLKOUT_DIV2) /* tuner divides by 2 */
{
ref_clk_divider = PHANTOM_REF_CLK_DIV1; /* now the demod divides by 1 */
}
if (PHANTOM_RegisterWrite (p_nim, PHANTOM_SC_E5_REF_CLK_DIV, ref_clk_divider, PHANTOM_USE_DEMOD_HANDLE) == False)
{
CSTRACE(ERROR_LEVEL,"PHANTOM_RegisterWrite error\r\n");
PHANTOM_DBG_SET_ERROR(PHANTOM_REG_WRITE_ERR);
return (False);
}
/**************************************************************************
* Check and verify driver type *
**************************************************************************/
demod = PHANTOM;
/*if (PHANTOM_DRIVER_CxType(p_nim, &demod, NULL) == False)
{
return(False);
}*/
/**************************************************************************
* Set MPEG output *
**************************************************************************/
/* Initiate MPEG system */
if (PHANTOM_SetOutputOptions(p_nim, p_mpeg) == False)
{
CSTRACE(ERROR_LEVEL,"PHANTOM_SetOutputOptions error\r\n");
return(False);
}
p_nim->track_state = PHANTOM_TRACK_INIT;
p_nim->tuner_bw_adjust = False;
return(True);
} /* PHANTOM_InitEnvironment() */
/*******************************************************************************************************
* PHANTOM_ProgramOutputRate(). Call once after the demod is locked to adjust the rate
* for extra clocks between MPEG packets.
*******************************************************************************************************/
BOOL
PHANTOM_ProgramOutputRate(PHANTOM_NIM* p_nim)
{
PHANTOM_M_N bit_rate_constant, new_bit_rate_constant;
if (p_nim->mpeg_out.extra_clocks_between_packets != 0)
{
if (PHANTOM_LLF_GetMN(p_nim, &bit_rate_constant.m, &bit_rate_constant.n) == False)
{
return (False);
}
bit_rate_constant.m = PHANTOM_DRIVER_GetNewMN(&bit_rate_constant,
&new_bit_rate_constant,
p_nim->mpeg_out.extra_clocks_between_packets,
(p_nim->mpeg_out.insert_sync_byte == PHANTOM_SYNC_BYTE_INSERT) ? True : False,
(p_nim->mpeg_out.output_mode == PHANTOM_PARALLEL_OUT) ? True : False,
p_nim->rx_operation_mode,
p_nim->last_pilot);
if (PHANTOM_LLF_SetMN(p_nim,
p_nim->mpeg_out.extra_clocks_between_packets,
new_bit_rate_constant.m,
new_bit_rate_constant.n,
new_bit_rate_constant.m_n_rate) == False)
{
return (False);
}
}
return (True);
}
/*******************************************************************************************************
* PHANTOM_ChangeChannel()
* High-level function to perform channel-change operation
*******************************************************************************************************/
BOOL
PHANTOM_ChangeChannel(PHANTOM_NIM* p_nim, /* nim pointer */
PHANTOM_CHANOBJ* p_channel_object) /* channel struct containing pert. channel info */
{
unsigned short nominal_central_frequency = 0;
unsigned long pll_main_clk_divider;
unsigned long adc_mode_sel = 0;
unsigned long vco_clk_by_main_div = 0;
/**************************************************************************
* Part1: Input validation
**************************************************************************/
/* test for valid nim */
if (PHANTOM_DRIVER_ValidateNim(p_nim) == False)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_BAD_PARM);
return(False);
}
/* if channel object is bad, bale out immediately */
if (p_channel_object == 0)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_BAD_PARM);
return(False);
}
/**************************************************************************
* Part2: Set LNB parameters. *
**************************************************************************/
/* Set LNB DC Polarity 13v/18v */
/*if (PHANTOM_SetLNBDC(p_nim, p_channel_object->lnbdc) == False)
{
return (False);
} */
/* Set the LNB Tone */
/*if (PHANTOM_SetLNBTone(p_nim, p_channel_object->lnbtone) == False)
{
return(False);
}*/
/**************************************************************************
* Part3: Set demod parameters. *
**************************************************************************/
adc_mode_sel = PHANTOM_ADC_MOD_SEL_DIV6;
pll_main_clk_divider = PHANTOM_PLL_MAIN_CLOCK_DIV6;
if (p_channel_object->symbrate > PHANTOM_SYMBRATE_LIMIT_4) /* 30 to 45 Msps */
{
adc_mode_sel = PHANTOM_ADC_MOD_SEL_DIV4;
pll_main_clk_divider = PHANTOM_PLL_MAIN_CLOCK_DIV4;
}
if (PHANTOM_RegisterWrite (p_nim, PHANTOM_SC_F3_PLL_MAIN_CLK_DIV, pll_main_clk_divider, PHANTOM_USE_DEMOD_HANDLE) == False)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_REG_WRITE_ERR);
return (False);
}
if (PHANTOM_RegisterWrite (p_nim, PHANTOM_SC_F9_ADC_MODE_SEL, adc_mode_sel, PHANTOM_USE_DEMOD_HANDLE) == False)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_REG_WRITE_ERR);
return (False);
}
p_nim->sample_frequency = p_nim->vco_freq / pll_main_clk_divider;
p_nim->last_pilot = p_channel_object->pilot;
/**************************************************************************
* Part4: Re-start acquisition. *
**************************************************************************/
if (p_channel_object->acqmode == PHANTOM_ACQ_MODE_BLIND || p_channel_object->acqmode == PHANTOM_ACQ_MODE_INSTALLATION)
{
nominal_central_frequency = 0;
}
p_nim->freq_ideal = p_channel_object->frequency;
p_nim->rx_operation_mode = p_channel_object->rx_operation_mode;
p_nim->symbol_rate = p_channel_object->symbrate;
vco_clk_by_main_div = (p_nim->vco_freq/pll_main_clk_divider)/1000; /* sample rate in khz */
p_nim->prev_acqstate = PHANTOM_ACQ_SEARCHING;
/* Change channel */
if (PHANTOM_LLF_ChangeChannel(p_nim,
p_channel_object->frequency,
(unsigned short)(p_channel_object->symbrate), /* nominal symbol rate */
(unsigned char)(p_channel_object->acqmode), /* acq. mode */
(unsigned char)(p_channel_object->specinv), /* spectral inversion */
(unsigned char)(p_channel_object->rx_operation_mode), /* receiver operation mode */
(unsigned char)(p_channel_object->pilot), /* pilot */
p_channel_object->requested_search_range, /* frequency_search_range */
nominal_central_frequency,
(unsigned char)(p_channel_object->rolloff),
(unsigned char)(p_channel_object->viterbicoderates),
(unsigned char)pll_main_clk_divider,
vco_clk_by_main_div) == False)
{
return (False);
}
p_nim->tuner_bw_adjust = True;
if (p_nim->mpeg_out.extra_clocks_between_packets != 0)
{
p_nim->mpeg_clock_rate_adjust = True;
}
else
{
p_nim->mpeg_clock_rate_adjust = False;
}
return(True);
} /* PHANTOM_ChangeChannel() */
/*******************************************************************************************************
* PHANTOM_Monitor()
* Monitors the demod after a successful channel change operation
*******************************************************************************************************/
BOOL
PHANTOM_Monitor(PHANTOM_NIM* p_nim, /* pointer to PHANTOM_NIM */
PHANTOM_ACQ_STATE* p_state, /* storage for returned acqusition state of demod */
PHANTOM_LOCKIND* p_lockinds)/* storage for returned demod lock indicators */
{
/* test for valid nim */
if (PHANTOM_DRIVER_ValidateNim(p_nim) == False)
{
PHANTOM_DBG_SET_ERROR(PHANTOM_BAD_PARM);
return(False);
}
if (p_state == 0 || p_lockinds == 0)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?