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

📄 drx3973d.c

📁 用于DRX3973或DRX39系列的芯片的控制
💻 C
📖 第 1 页 / 共 5 页
字号:
   0,             /* ucode size */
   TRUE,          /* ucode verify switch */
   0,             /* IF in kHz in case no tuner instance is used */
   48000L,        /* system clock frequency in kHz */
   20000L,        /* oscillator frequency kHz*/
   0L,            /* oscillator deviation in ppm, signed */
   FALSE,         /* If TRUE mirror frequency spectrum */

   /* MPEG output configuration */
   TRUE,          /* If TRUE, enable MPEG ouput */
   TRUE,          /* If TRUE, insert RS byte */
   TRUE,          /* If TRUE, parallel out otherwise serial */
   FALSE,         /* If TRUE, invert DATA signals */
   FALSE,         /* If TRUE, invert ERR signal */
   FALSE,         /* If TRUE, invert STR signals */
   FALSE,         /* If TRUE, invert VAL signals */
   FALSE,         /* If TRUE, invert CLK signals */

   FALSE,               /* isOpened */

   /* Scan */
   NULL,                /* no scan params yet */
   0,                   /* current scan index */
   0,                   /* next scan frequency */
   FALSE,               /* scan ready flag */
   0L,                  /* max channels to scan */
   0L,                  /* nr of channels scanned */
   0,                   /* millisec to wait for demod lock */
   DRX3973D_DEMOD_LOCK, /* desired lock */
   FALSE,               /* scan routines active or not */

   /* Power management */
   DRX_POWER_DOWN,

   /* Tuner */
   1,                   /* nr of I2C port to wich tuner is */
   0L,                  /* minimum RF input frequency, in kHz */
   0L                   /* maximum RF input frequency, in kHz */
};


/**
* \var DRX3973DDefaultDemod_g
* \brief Default drx3973d demodulator instance.
*/
DRXDemodInstance_t DRX3973DDefaultDemod_g = {
   &DRX3973DFunctions_g,          /* demod functions */
   &DRX3973D_DAP,                 /* data access protocol functions */
   NULL,                          /* tuner instance */
   &DRX3973DDefaultAddr_g,        /* i2c address & device id */
   &DRX3973DDefaultCommAttr_g,    /* demod common attributes */
   &DRX3973DData_g                /* demod device specific attributes */
};

/*-----------------------------------------------------------------------------
STRUCTURES
----------------------------------------------------------------------------*/

typedef struct {
   u16_t cmd;
   u16_t param1;
   u16_t param2;
   u16_t param3;
   u16_t param4;
   u16_t param5;
} DRX3973DHiCmd_t, *pDRX3973DHiCmd_t;

/*-----------------------------------------------------------------------------
FUNCTIONS
----------------------------------------------------------------------------*/
/* Some prototypes */
static DRXStatus_t CtrlI2CBridge( pDRXDemodInstance_t demod,
                                  pBool_t             bridgeClosed );

static DRXStatus_t CtrlUIOWrite( pDRXDemodInstance_t demod,
                                 pDRXUIOData_t       UIOData);

static DRXStatus_t CtrlLockStatus( pI2CDeviceAddr_t  devAddr,
                                   pDRXLockStatus_t  lockStat );

static DRXStatus_t HI_CfgCommand(const pDRXDemodInstance_t   demod);

static DRXStatus_t
CtrlSetCfgIfAgc( pDRXDemodInstance_t   demod, pDRX3973DCfgAgc_t cfg );

static DRXStatus_t
CtrlSetCfgRfAgc( pDRXDemodInstance_t   demod, pDRX3973DCfgAgc_t cfg );

static DRXStatus_t
HI_Command(const pI2CDeviceAddr_t devAddr,
           const pDRX3973DHiCmd_t cmd,
           pu16_t result);

/*=============================================================================
  =============================================================================
  ===== HELPER FUNCTIONS ======================================================
  =============================================================================
  ===========================================================================*/

/*============================================================================*/

/**
* \fn void WaitMilliSec()
* \brief Wait (loop) at least n millisec
* \param n millisec to wait
*
*/
static DRXStatus_t WaitMilliSec(u16_t n)
{
   u32_t start=0;
   u32_t current=0;
   u32_t delta=0;

   start = DRXBSP_HST_Clock();

   do{
      current = DRXBSP_HST_Clock();
      delta = current - start;
   } while( delta < n );

   return (DRX_STS_OK);
}

/*============================================================================*/


/**
* \fn void Mult32(u32_t a, u32_t b, pu32_t h, pu32_t l)
* \brief 32bitsx32bits signed multiplication
* \param a 32 bits multiplicant
* \param b 32 bits multiplier
* \param h pointer to high part 64 bits result
* \param l pointer to low part 64 bits result
*/

static void  Mult32(u32_t a, u32_t b, ps32_t h, pu32_t l)
{

   u8_t i = 0;

   *l =0;
   *h =0;
   for ( i=0 ; i<32 ; i++)
   {
      if ( a & 1)
      {
         *h += b;
      }
      /* shift [h:l] one right */
      (*l) >>= 1;
      if ( (*h) & 1)
      {
         *l |= 0x80000000UL;
      }
      (*h) >>=1;
      /* shift multiplicant one right */
      a >>=1;
   }
}

/*============================================================================*/

static u32_t Frac28(u32_t N, u32_t D)
/*
   This function is used to avoid floating-point calculations as they may
   not be present on the target platform.

   Frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
   fraction used for setting the Frequency Shifter registers.
   N and D can hold numbers up to width: 28-bits.
   The 4 bits integer part and the 28 bits fractional part are calculated.

   Effectually calculates: (1<<28)*N/D

   N: 0...(1<<28)-1 = 268435454
   D: 0...(1<<28)-1
   Q: 0...(1<<32)-1
*/
{
   u8_t   i=0;
   u32_t Q1=0;
   u32_t R0=0;

   R0 = (N%D)<<4; /* 32-28 == 4 shifts possible at max */
   Q1 = N/D;      /* integer part, only the 4 least significant bits
                     will be visible in the result */

   /* division using radix 16, 7 nibbles in the result */
   for (i=0; i<7; i++) {
      Q1 = (Q1 << 4) | R0/D;
      R0 = (R0%D)<<4;
   }
   /* rounding */
   if ((R0>>3) >= D) Q1++;

   return Q1;
}

/*============================================================================*/

/**
* \fn u32_t FracTimes1e6( u16_t N, u32_t D)
* \brief Compute: (N/D) * 1000000.
* \param N nominator 16-bits.
* \param D denominator 32-bits.
* \return u32_t
* \retval ((N/D) * 1000000), 32 bits
*
* No check on D=0!
*/
static u32_t
FracTimes1e6( u16_t N, u32_t D)
{
   u32_t remainder = 0;
   u32_t frac = 0;

   /*
      frac = (N * 1000000) / D
      To let it fit in a 32 bits computation:
      frac = (N * (1000000 >> 4)) / (D >> 4)
      This would result in a problem in case D < 16 (div by 0).
      So we do it more elaborate as shown below.
   */

   frac =  ( ((u32_t)N) * (1000000UL >> 4) ) / D ;
   frac <<=  4 ;
   remainder  =  ( ((u32_t)N) * (1000000UL >> 4) ) % D ;
   remainder <<= 4;
   frac += remainder / D;
   remainder  = remainder % D ;
   if( (remainder * 2) > D )
   {
      frac++;
   }

   return ( frac );
}

/*============================================================================*/

/**
* \fn u32_t Log10Times100( u32_t x)
* \brief Compute: 100*log10(x)
* \param x 32 bits
* \return 100*log10(x)
*
* 100*log10(x)
* = 100*(log2(x)/log2(10)))
* = (100*(2^15)*log2(x))/((2^15)*log2(10))
* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
*
* where y = 2^k and 1<= (x/y) < 2
*/

u32_t Log10Times100( u32_t x)
{
   static const u8_t scale=15;
   static const u8_t indexWidth=5;
   /*
   log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
   0 <= n < ((1<<INDEXWIDTH)+1)
   */

   static const u32_t log2lut[] = {
      0, /* 0.000000 */
      290941, /* 290941.300628 */
      573196, /* 573196.476418 */
      847269, /* 847269.179851 */
      1113620, /* 1113620.489452 */
      1372674, /* 1372673.576986 */
      1624818, /* 1624817.752104 */
      1870412, /* 1870411.981536 */
      2109788, /* 2109787.962654 */
      2343253, /* 2343252.817465 */
      2571091, /* 2571091.461923 */
      2793569, /* 2793568.696416 */
      3010931, /* 3010931.055901 */
      3223408, /* 3223408.452106 */
      3431216, /* 3431215.635215 */
      3634553, /* 3634553.498355 */
      3833610, /* 3833610.244726 */
      4028562, /* 4028562.434393 */
      4219576, /* 4219575.925308 */
      4406807, /* 4406806.721144 */
      4590402, /* 4590401.736809 */
      4770499, /* 4770499.491025 */
      4947231, /* 4947230.734179 */
      5120719, /* 5120719.018555 */
      5291081, /* 5291081.217197 */
      5458428, /* 5458427.996830 */
      5622864, /* 5622864.249668 */
      5784489, /* 5784489.488298 */
      5943398, /* 5943398.207380 */
      6099680, /* 6099680.215452 */
      6253421, /* 6253420.939751 */
      6404702, /* 6404701.706649 */
      6553600, /* 6553600.000000 */
   };


   u8_t  i = 0;
   u32_t y = 0;
   u32_t d = 0;
   u32_t k = 0;
   u32_t r = 0;

   if (x==0) return (0);

   /* Scale x (normalize) */
   /* computing y in log(x/y) = log(x) - log(y) */
   if ( (x & (((u32_t)(-1))<<(scale+1)) ) == 0 )
   {
      for (k = scale; k>0 ; k--)
      {
        if (x & (((u32_t)1)<<scale)) break;
        x <<= 1;
      }
   } else {
      for (k = scale; k<31 ; k++)
      {
        if ((x & (((u32_t)(-1))<<(scale+1)))==0) break;
        x >>= 1;
      }
   }
   /*
     Now x has binary point between bit[scale] and bit[scale-1]
     and 1.0 <= x < 2.0 */

   /* correction for divison: log(x) = log(x/y)+log(y) */
   y = k * ( ( ((u32_t)1) << scale ) * 200 );

   /* remove integer part */
   x &= ((((u32_t)1) << scale)-1);
   /* get index */
   i = (u8_t) (x >> (scale -indexWidth));
   /* compute delta (x-a) */
   d = x & ((((u32_t)1) << (scale-indexWidth))-1);
   /* compute log, multiplication ( d* (.. )) must be within range ! */
   y += log2lut[i] + (( d*( log2lut[i+1]-log2lut[i] ))>>(scale-indexWidth));
   /* Conver to log10() */
   y /= 108853; /* (log2(10) << scale) */
   r = (y>>1);
   /* rounding */
   if (y&((u32_t)1)) r++;

   return (r);

}

/*=============================================================================
  ===== Atomic data access related stuff ======================================
  ===========================================================================*/

#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A

static
DRXStatus_t InitAtomicRead ( pI2CDeviceAddr_t devAddr )
{
   static u8_t instructions[] =
   {
     0x26, 0x00,  /* 0         -> ring.rdy;           */
     0x60, 0x04,  /* r0rami.dt -> ring.xba;           */
     0x61, 0x04,  /* r0rami.dt -> ring.xad;           */
     0xE3, 0x07,  /* HI_RA_RAM_USR_BEGIN -> ring.iad; */
     0x40, 0x00,  /* (long immediate)                 */
     0x64, 0x04,  /* r0rami.dt -> ring.len;           */
     0x65, 0x04,  /* r0rami.dt -> ring.ctl;           */
     0x26, 0x00,  /* 0         -> ring.rdy;           */
     0x38, 0x00   /* 0         -> jumps.ad;           */
   };

   WRBLOCK( devAddr, HI_TR_FUNC_ADDR , sizeof(instructions), instructions );

   return DRX_STS_OK;

 rw_error:
   return (DRX_STS_ERROR);
}

/**
* \fn DRXStatus_t AtomicReadBlock()
* \brief Atomic read of n bytes
*
* Flags are ignored for now ...
*/

#define HI_TR_WRITE      0x9
#define HI_TR_READ       0xA
#define HI_TR_READ_WRITE 0xB
#define HI_TR_BROADCAST  0x4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -