📄 tunerxc3028.c
字号:
/**
* \file $Id: tunerxc3028.c,v 1.5 2005/11/22 16:40:13 paulja Exp $
*
* \brief DRXBSP tuner implementation for XC3028.
*
* \author Jasper Schrader
*/
/*
* $(c) 2005 Micronas GmbH. All rights reserved.
*
* This software and related documentation (the 'Software') are intellectual
* property owned by Micronas and are copyright of Micronas, unless specifically
* noted otherwise.
*
* Any use of the Software is permitted only pursuant to the terms of the
* license agreement, if any, which accompanies, is included with or applicable
* to the Software ('License Agreement') or upon express written consent of
* Micronas. Any copying, reproduction or redistribution of the Software in
* whole or in part by any means not in accordance with the License Agreement
* or as agreed in writing by Micronas is expressly prohibited.
*
* THE SOFTWARE IS WARRANTED, IF AT ALL, ONLY ACCORDING TO THE TERMS OF THE
* LICENSE AGREEMENT. EXCEPT AS WARRANTED IN THE LICENSE AGREEMENT THE SOFTWARE
* IS DELIVERED 'AS IS' AND MICRONAS HEREBY DISCLAIMS ALL WARRANTIES AND
* CONDITIONS WITH REGARD TO THE SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIT
* ENJOYMENT, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL
* PROPERTY OR OTHER RIGHTS WHICH MAY RESULT FROM THE USE OR THE INABILITY
* TO USE THE SOFTWARE.
*
* IN NO EVENT SHALL MICRONAS BE LIABLE FOR INDIRECT, INCIDENTAL, CONSEQUENTIAL,
* PUNITIVE, SPECIAL OR OTHER DAMAGES WHATSOEVER INCLUDING WITHOUT LIMITATION,
* DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
* INFORMATION, AND THE LIKE, ARISING OUT OF OR RELATING TO THE USE OF OR THE
* INABILITY TO USE THE SOFTWARE, EVEN IF MICRONAS HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES, EXCEPT PERSONAL INJURY OR DEATH RESULTING FROM
* MICRONAS' NEGLIGENCE. $
*
*/
/*-----------------------------------------------------------------------------
INCLUDE FILES
----------------------------------------------------------------------------*/
#include "drx3973d.h"
#include "tunerxc3028.h"
#if (USE_DUMMY_XC3028!=1)
#include "xc3028_control.h"
#include "xc3028_channelmaps.h"
#include "xc3028_scodes.h"
#include "xc3028_firmwares.h"
#endif /* (USE_DUMMY_XC3028!=1) */
/*-----------------------------------------------------------------------------
STATIC VARIABLES
----------------------------------------------------------------------------*/
static pTUNERInstance_t currentXC3028Tuner = NULL;
static pDRXDemodInstance_t currentXC3028Demod = NULL;
/*------------------------------------------------------------------------------
GLOBAL VARIABLES
------------------------------------------------------------------------------*/
TUNERFunc_t TUNERXC3028Functions_g = {
TUNER_XC3028_Open,
TUNER_XC3028_Close,
TUNER_XC3028_SetFrequency,
TUNER_XC3028_GetFrequency,
TUNER_XC3028_LockStatus,
DRXBSP_TUNER_DefaultI2CWriteRead
};
/*-----------------------------------------------------------------------------
FUNCTIONS
----------------------------------------------------------------------------*/
#if (USE_DUMMY_XC3028==1)
/*****************************************************************************
**
** Dummy interface implementation needed to compile WITHOUT Xceive
** source files.
**
*****************************************************************************/
#define XC3028_RESULT_SUCCESS 0
#define XC3028_RESULT_RESET_FAILURE 1
#define XC3028_RESULT_I2C_WRITE_FAILURE 2
#define XC3028_RESULT_I2C_READ_FAILURE 3
typedef struct {
unsigned char *sequence;
} XC3028_I2C_SEQUENCE;
typedef unsigned char XC3028_SCODE_TABLE[16][12];
typedef struct {
char identifier[4];
unsigned int frequency;
unsigned char dcode;
} XC3028_CHANNEL;
typedef struct {
int nb_channels;
XC3028_CHANNEL *channels;
} XC3028_CHANNEL_MAP;
typedef struct {
XC3028_I2C_SEQUENCE *base_firmware_ptr;
XC3028_I2C_SEQUENCE *std_firmware_ptr;
XC3028_SCODE_TABLE *scode_table_ptr;
} XC3028_TV_MODE;
int xc3028_initialize(XC3028_TV_MODE* new_tv_mode_ptr, XC3028_CHANNEL_MAP* new_channel_map_ptr)
{
return (XC3028_RESULT_RESET_FAILURE );
}
int xc3028_set_frequency(double frequency_in_mhz)
{
return (XC3028_RESULT_RESET_FAILURE );
}
XC3028_TV_MODE XC3028_tv_mode_dtv6_qam_6_0mhz;
XC3028_TV_MODE XC3028_tv_mode_dtv78_dibcom_5_2mhz;
XC3028_CHANNEL_MAP XC3028_channel_map_ccir_air;
#endif /* (USE_DUMMY_XC3028==1) */
/**
* \fn xc3028_send_i2c_data()
* \brief Function to write data to the XC3028 via i2c.
* \return int.
* \retval XC3028_RESULT_SUCCESS: All OK.
* \retval XC3028_RESULT_I2C_WRITE_FAILURE: Something went wrong.
*
*/
int xc3028_send_i2c_data(unsigned char *bytes_to_send, int nb_bytes_to_send)
{
DRXStatus_t sts = DRX_STS_OK;
sts = (currentXC3028Tuner->myFunct->i2cWriteReadFunc)( currentXC3028Tuner, &(currentXC3028Tuner->myI2CDevAddr), (u16_t) nb_bytes_to_send, bytes_to_send, NULL, 0, NULL);
if (sts != DRX_STS_OK)
{
return XC3028_RESULT_I2C_WRITE_FAILURE;
}
return XC3028_RESULT_SUCCESS;
}
/*============================================================================*/
/**
* \fn xc3028_read_i2c_data()
* \brief Function to read data from the XC3028 via i2c.
* \return int.
* \retval XC3028_RESULT_SUCCESS: All OK.
* \retval XC3028_RESULT_I2C_READ_FAILURE: Something went wrong.
*
*/
int xc3028_read_i2c_data(unsigned char *bytes_received, int nb_bytes_to_receive)
{
DRXStatus_t sts = DRX_STS_OK;
sts = currentXC3028Tuner->myFunct->i2cWriteReadFunc( currentXC3028Tuner, NULL, 0, NULL, &(currentXC3028Tuner->myI2CDevAddr), (u16_t) nb_bytes_to_receive, bytes_received);
if (sts != DRX_STS_OK) return XC3028_RESULT_I2C_READ_FAILURE;
return XC3028_RESULT_SUCCESS;
}
/*============================================================================*/
/**
* \fn xc3028_wait()
* \brief Function to wait a specified number of milliseconds.
* \return int.
* \retval XC3028_RESULT_SUCCESS: All OK.
*
*/
int xc3028_wait(int wait_ms)
{
u32_t start = 0;
u32_t current= 0;
u32_t delta = 0;
u16_t n = (u16_t) wait_ms;
start = DRXBSP_HST_Clock();
do{
current = DRXBSP_HST_Clock();
delta = current - start;
} while( delta < n );
return XC3028_RESULT_SUCCESS;
}
/*============================================================================*/
/**
* \fn xc3028_reset()
* \brief Function to reset the XC3028 via the DRX397xD's UIO.
* \return int.
* \retval XC3028_RESULT_SUCCESS: All OK.
* \retval XC3028_RESULT_RESET_FAILURE: Something went wrong.
*
*/
int xc3028_reset()
{
DRXStatus_t status = DRX_STS_OK;
DRX3973DCfgAgc_t cfgRfAgc = {
DRX3973D_AGC_CTRL_USER, /* ctrlMode */
0, /* outputLevel */
0, /* settleLevel */
0, /* minOutputLevel */
0, /* maxOutputLevel */
0 /* Speed */
};
DRXCfg_t CfgSet = { DRX3973D_CFG_RF_AGC, &cfgRfAgc };
/* verify demod assignment */
if ( currentXC3028Demod == NULL ) return XC3028_RESULT_RESET_FAILURE;
/* reset */
cfgRfAgc.outputLevel = 0;
status = DRX_Ctrl( currentXC3028Demod, DRX_CTRL_SET_CFG, &CfgSet );
if ( status != DRX_STS_OK ) return XC3028_RESULT_RESET_FAILURE;
xc3028_wait(100);
/* un-reset */
cfgRfAgc.outputLevel = 1023;
status = DRX_Ctrl( currentXC3028Demod, DRX_CTRL_SET_CFG, &CfgSet );
if ( status != DRX_STS_OK ) return XC3028_RESULT_RESET_FAILURE;
xc3028_wait(10);
return XC3028_RESULT_SUCCESS;
}
/**
* \fn DRXStatus_t TUNER_XC3028_Open( pTUNERInstance_t tuner )
* \brief Open a tuner.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Opened tuner with success.
* \retval DRX_STS_ERROR Something went wrong.
*/
DRXStatus_t
TUNER_XC3028_Open( pTUNERInstance_t tuner )
{
/* Refresh static variables */
if ( (tuner -> myCommonAttr -> myUserData) == NULL)
{
return DRX_STS_ERROR;
}
currentXC3028Tuner = tuner;
currentXC3028Demod = (pDRXDemodInstance_t) ( tuner -> myCommonAttr -> myUserData );
return DRX_STS_OK;
}
/*============================================================================*/
/**
* \fn DRXStatus_t DRXBSP_TUNER_Close( pTUNERInstance_t tuner )
* \brief Close a tuner.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Closed tuner with success.
* \retval DRX_STS_ERROR Something went wrong.
*/
DRXStatus_t
TUNER_XC3028_Close( pTUNERInstance_t tuner )
{
/* No operation */
return( DRX_STS_OK );
}
/*============================================================================*/
/**
* \fn DRXStatus_t DRXBSP_TUNER_SetFrequency( pTUNERInstance_t tuner,
TUNERMode_t mode,
DRXFrequency_t centerFrequency )
* \brief Program tuner at given center frequency for given mode.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Programmed tuner successfully.
* \retval DRX_STS_ERROR Something went wrong.
*/
DRXStatus_t
TUNER_XC3028_SetFrequency( pTUNERInstance_t tuner,
TUNERMode_t mode,
DRXFrequency_t centerFrequency )
{
int result;
if ( ( centerFrequency < ( tuner->myCommonAttr->minFreqRF) ) ||
( centerFrequency > ( tuner->myCommonAttr->maxFreqRF) ) )
{
/* frequency out of range for this tuner */
return DRX_STS_ERROR;
}
/* determine bandwidth */
switch ( mode & (TUNER_MODE_6MHZ | TUNER_MODE_7MHZ | TUNER_MODE_8MHZ) )
{
case TUNER_MODE_6MHZ:
/* Load proper firmware (only done when different from previous channel) */
result = xc3028_initialize( &XC3028_tv_mode_dtv6_qam_6_0mhz,
&XC3028_channel_map_ccir_air );
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Program frequency */
result = xc3028_set_frequency((((double) centerFrequency )/1000) - 1.75);
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Store parameters */
tuner->myCommonAttr->RFfrequency = centerFrequency;
tuner->myCommonAttr->IFfrequency = 6000;
break;
case TUNER_MODE_7MHZ:
/* Load proper firmware (only done when different from previous channel) */
result = xc3028_initialize( &XC3028_tv_mode_dtv78_dibcom_5_2mhz,
&XC3028_channel_map_ccir_air );
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Program frequency */
result = xc3028_set_frequency((((double) centerFrequency )/1000) - 2.25);
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Store parameters */
tuner->myCommonAttr->RFfrequency = centerFrequency;
tuner->myCommonAttr->IFfrequency = 5200;
break;
case TUNER_MODE_8MHZ:
/* Load proper firmware (only done when different from previous channel) */
result = xc3028_initialize( &XC3028_tv_mode_dtv78_dibcom_5_2mhz,
&XC3028_channel_map_ccir_air );
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Program frequency */
result = xc3028_set_frequency((((double) centerFrequency )/1000) - 2.75);
if (result != XC3028_RESULT_SUCCESS)
{
return DRX_STS_ERROR;
}
/* Store parameters */
tuner->myCommonAttr->RFfrequency = centerFrequency;
tuner->myCommonAttr->IFfrequency = 5200;
break;
default:
return (DRX_STS_ERROR);
}
return( DRX_STS_OK );
}
/*============================================================================*/
/**
* \fn DRXStatus_t DRXBSP_TUNER_GetFrequency( pTUNERInstance_t tuner,
pDRXFrequency_t RFfrequency,
pDRXFrequency_t IFfrequency )
* \brief Get tuned center frequency.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Returned frequency successfully.
* \retval DRX_STS_ERROR Something went wrong.
*/
DRXStatus_t
TUNER_XC3028_GetFrequency( pTUNERInstance_t tuner,
pDRXFrequency_t RFfrequency,
pDRXFrequency_t IFfrequency )
{
if ( RFfrequency != NULL )
{
*RFfrequency = tuner->myCommonAttr->RFfrequency;
}
if ( IFfrequency != NULL )
{
*IFfrequency = tuner->myCommonAttr->IFfrequency;
}
return( DRX_STS_OK );
}
/*============================================================================*/
/**
* \fn DRXStatus_t DRXBSP_TUNER_LockStatus( pTUNERInstance_t tuner,
pTUNERLockStatus_t lockStat )
* \brief Get tuner locking status.
* \return DRXStatus_t Return status.
* \retval DRX_STS_OK Acquired locking status successfully.
* \retval DRX_STS_ERROR Something went wrong.
*/
DRXStatus_t
TUNER_XC3028_LockStatus( pTUNERInstance_t tuner,
pTUNERLockStatus_t lockStat )
{
/* Lock retrieval is only possible for analog demodulation in the XC3028 */
/* TUNER_LOCKED is returned, to avoid unneccessary thread lock-ups */
*lockStat = TUNER_LOCKED;
return DRX_STS_OK;
}
/*============================================================================*/
/* End of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -