⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tunerxc3028.c

📁 用于DRX3973或DRX39系列的芯片的控制
💻 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 + -