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

📄 drx_driver.c

📁 用于DRX3973或DRX39系列的芯片的控制
💻 C
📖 第 1 页 / 共 3 页
字号:
               maxFreq = lastFreq;
            } else {
               u32_t n=0;

               n=( lastFreq - maxTunerFreq )/step;
               if ( (( lastFreq - maxTunerFreq )%step) !=0 )
               {
                  n++;
               }
               maxFreq = lastFreq - n*step;
            }
         }
      }

      /* Keep track of total number of channels within tuner range
         in this frequency plan. */
      if ( (minFreq!=0) && (maxFreq!=0) )
      {
         nrChannelsInPlan += (u16_t)(( (maxFreq-minFreq) / step ) +1 );

         /* Determine first frequency (within tuner range) to scan */
         if ( commonAttr->scanNextFrequency == 0 )
         {
            commonAttr->scanNextFrequency = minFreq;
            commonAttr->scanFreqPlanIndex = i;
         }
      }

   }/* for ( ... ) */

   if ( nrChannelsInPlan == 0 )
   {
      /* Tuner range and frequency plan ranges do not overlap */
      commonAttr->scanActive = FALSE;
      return (DRX_STS_ERROR);
   }

   /* Store parameters */
   commonAttr->scanReady = FALSE;
   commonAttr->scanMaxChannels = nrChannelsInPlan;
   commonAttr->scanChannelsScanned = 0;
   commonAttr->scanParam = scanParam; /* SCAN_NEXT is now allowed */

   commonAttr->scanActive = FALSE;

   return (DRX_STS_OK);
}

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

/**
* \fn DRXStatus_t CtrlScanNext()
* \brief Scan for next channel .
* \param demod Pointer to demodulator instance.
* \param scanParam Pointer to scan parameters.
* \return DRXStatus_t.
* \retval DRX_STS_OK Channel found.
* \retval DRX_STS_BUSY Tried specified number of channels, need to scan more.
* \retval DRX_STS_READY Reached end of scan range.
* \retval DRX_STS_ERROR Something went wrong.
* \retval DRX_STS_INVALID_ARG Wrong parameters.
*
*/
static DRXStatus_t
CtrlScanNext( pDRXDemodInstance_t  demod,
              pu16_t               scanProgress )
{
   pDRXCommonAttr_t  commonAttr=NULL;
   pBool_t scanReady = NULL;
   u16_t maxProgress = DRX_SCAN_MAX_PROGRESS;
   u32_t numTries = 0;
   u32_t i = 0;

   /* Check scan parameters */
   *scanProgress = 0;
   commonAttr = (pDRXCommonAttr_t)demod -> myCommonAttr;
   commonAttr->scanActive = TRUE;
   if ( (commonAttr->scanParam == NULL) ||
        ( commonAttr->scanMaxChannels == 0 )
      )
   {
      /* CtrlScanInit() was not called succesfully before CtrlScanNext() */
      commonAttr->scanActive = FALSE;
      return (DRX_STS_ERROR);
   }

   *scanProgress = (u16_t)(((commonAttr->scanChannelsScanned)*
                           ((u32_t)(maxProgress)))/
                           (commonAttr->scanMaxChannels));

   /* Scan */
   numTries = commonAttr->scanParam->numTries;
   scanReady = &(commonAttr->scanReady);
   for ( i = 0; ( (i < numTries) && ( (*scanReady) == FALSE) ); i++)
   {
      DRXChannel_t         scanChannel;
      DRXStatus_t          status      = DRX_STS_ERROR;
      Bool_t               isLocked    = FALSE;
      pDRXFrequencyPlan_t  freqPlan    = NULL;


      /* Next channel to scan */
      freqPlan =
        &(commonAttr->scanParam->frequencyPlan[commonAttr->scanFreqPlanIndex]);
      scanChannel.frequency      = commonAttr->scanNextFrequency;
      scanChannel.bandwidth      = freqPlan->bandwidth;
      scanChannel.mirror         = DRX_AUTO;
      scanChannel.constellation  = DRX_AUTO;
      scanChannel.hierarchy      = DRX_AUTO;
      scanChannel.priority       = DRX_PRIORITY_HIGH;
      scanChannel.coderate       = DRX_AUTO;
      scanChannel.guard          = DRX_AUTO;
      scanChannel.fftmode        = DRX_AUTO;
      scanChannel.classification = DRX_AUTO;


      /* Scan (try) that frequency */
      status = DRX_Ctrl( demod, DRX_CTRL_SET_CHANNEL, &scanChannel );
      if ( status != DRX_STS_OK )
      {
         commonAttr->scanActive = FALSE;
         return (status);
      }

      /* Determine frequency to scan next time
         side effects:
            commonAttr->scanFreqPlanIndex
            commonAttr->scanNextFrequency
            commonAttr->scanReady
      */
      status = ScanPrepareNextScan( demod );
      if ( status != DRX_STS_OK )
      {
         commonAttr->scanActive = FALSE;
         return (status);
      }

      /* Keep track of progress */
      (commonAttr->scanChannelsScanned) ++;
      *scanProgress = (u16_t)(((commonAttr->scanChannelsScanned)*
                              ((u32_t)(maxProgress)))/
                             (commonAttr->scanMaxChannels));


      status = ScanWaitForLock( demod, &isLocked );
      if ( status != DRX_STS_OK )
      {
         commonAttr->scanActive = FALSE;
         return (status);
      }

      if ( isLocked == TRUE )
      {
         /* Channel found */
         commonAttr->scanActive = FALSE;
         return (DRX_STS_OK);
      }
   } /* for ( i = 0; i < ( ... numTries); i++) */

   if ( (*scanReady) == TRUE )
   {
      commonAttr->scanActive = FALSE;
      return (DRX_STS_READY);
   }

   commonAttr->scanActive = FALSE;

   return (DRX_STS_BUSY);
}

/*============================================================================*/
/*============================================================================*/
/*===Microcode related functions==============================================*/
/*============================================================================*/
/*============================================================================*/

/**
* \fn u16_t UCodeRead16( pu8_t addr)
* \brief Read a 16 bits word, expect big endian data.
* \return u16_t The data read.
*/
static u16_t
UCodeRead16( pu8_t addr)
{
   /* Works fo any host processor */

   u16_t word=0;

   word = addr[0];
   word <<= 8;
   word |= addr[1];

   return ( word );
}

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

/**
* \fn u32_t UCodeRead32( pu8_t addr)
* \brief Read a 32 bits word, expect big endian data.
* \return u32_t The data read.
*/
static u32_t
UCodeRead32( pu8_t addr)
{
   /* Works fo any host processor */

   u32_t word=0;

   word = addr[0];
   word <<= 8;
   word |= addr[1];
   word <<= 8;
   word |= addr[2];
   word <<= 8;
   word |= addr[3];

   return ( word );
}

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

/**
* \fn u16_t UCodeComputeCRC (pu8_t blockData, u16_t nrWords)
* \brief Compute CRC of block of microcode data.
* \param blockData Pointer to microcode data.
* \param nrWords Size of microcode block (number of 16 bits words).
* \return u16_t The computed CRC residu.
*/
static u16_t
UCodeComputeCRC (pu8_t blockData, u16_t nrWords)
{
   u16_t i = 0;
   u8_t  j = 0;
   u32_t CRCWord=0;
   u32_t carry=0;

   while (i < nrWords) {
     CRCWord |= (u32_t) UCodeRead16(blockData);
     for (j = 0; j < 16; j++)
     {
       CRCWord <<= 1;
       if (carry != 0)
          CRCWord ^= 0x80050000UL;
       carry = CRCWord & 0x80000000UL;
     }
     i++;
     blockData+=(sizeof(u16_t));
  }
  return ((u16_t) (CRCWord >> 16));
}

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

/**
* \fn DRXStatus_t CtrlUCode()
* \brief Handle microcode upload or verify.
* \param devAddr Address of device.
* \param mcInfo  Pointer to information about microcode data.
* \param action  Either UCODE_UPLOAD or UCODE_VERIFY
* \return DRXStatus_t.
*/
static DRXStatus_t
CtrlUCode( pDRXDemodInstance_t demod,
           pDRXUCodeInfo_t  mcInfo,
           DRXUCodeAction_t action)
{
   u16_t  i = 0;
   u16_t  mcNrOfBlks = 0;
   u16_t  mcMagicWord = 0;
   pu8_t  mcData = NULL;
   pI2CDeviceAddr_t devAddr = NULL;

   devAddr = demod -> myI2CDevAddr;

   /* Check arguments */
   if ( ( mcInfo == NULL ) ||
        ( mcInfo->mcData == NULL ) ||
        ( mcInfo->mcSize == 0 ) )
   {
      return DRX_STS_INVALID_ARG;
   }

   mcData = mcInfo->mcData;

   /* Check data */
   mcMagicWord = UCodeRead16( mcData );
   mcData += sizeof( u16_t );
   mcNrOfBlks = UCodeRead16( mcData );
   mcData += sizeof( u16_t );

   if ( ( mcMagicWord != UCODE_MAGIC_WORD ) ||
        ( mcNrOfBlks == 0 ) )
   {
      /* wrong endianess or wrong data ? */
      return DRX_STS_INVALID_ARG;
   }

   /* Process microcode blocks */
   for( i = 0 ; i<mcNrOfBlks ; i++ )
   {
      DRXUCodeBlockHdr_t blockHdr;
      u16_t mcBlockNrBytes = 0;

      /* Process block header */
      blockHdr.addr = UCodeRead32( mcData );
      mcData += sizeof(u32_t);
      blockHdr.size = UCodeRead16( mcData );
      mcData += sizeof(u16_t);
      blockHdr.flags = UCodeRead16( mcData );
      mcData += sizeof(u16_t);
      blockHdr.CRC = UCodeRead16( mcData );
      mcData += sizeof(u16_t);

      /* Check block data */
      if ( ( blockHdr.size == 0 ) ||
           ( (( blockHdr.flags & UCODE_CRC_FLAG ) != 0) &&
             ( blockHdr.CRC != UCodeComputeCRC( mcData, blockHdr.size)) ) ||
           (( blockHdr.flags & UCODE_COMPRESSION_FLAG ) != 0)
         )
      {
         /* Wrong data ! */
         return DRX_STS_INVALID_ARG;
      }

      mcBlockNrBytes = blockHdr.size * sizeof(u16_t);

      /* Perform the desired action */
      switch ( action ) {
         /*===================================================================*/
         case UCODE_UPLOAD :
            {
               /* Upload microcode */
               if ( demod->myAccessFunct->writeBlockFunc(
                               devAddr,
                               (DRXaddr_t) blockHdr.addr,
                               mcBlockNrBytes,
                               mcData,
                               0x0000) != DRX_STS_OK)
               {
                  return (DRX_STS_OK);
               } /* if */
            };
            break;

         /*===================================================================*/
         case UCODE_VERIFY :
            {
               int result = 0;
               pu8_t  mcBlockData = NULL;

               /* Prepare for ucode download */
               mcBlockData = DRXBSP_HST_Malloc( (u32_t) mcBlockNrBytes );
               if ( mcBlockData == NULL )
               {
                  return DRX_STS_ERROR;
               }

               /* Download microcode block */
               if ( demod->myAccessFunct->readBlockFunc(
                              devAddr,
                              (DRXaddr_t) blockHdr.addr,
                              mcBlockNrBytes,
                              mcBlockData,
                              0x0000) != DRX_STS_OK)
               {
                  DRXBSP_HST_Free( mcBlockData );
                  return (DRX_STS_ERROR);
               }

               /* Verify microcode block */
               result = DRXBSP_HST_Memcmp( mcData, mcBlockData, (u32_t)mcBlockNrBytes);
               DRXBSP_HST_Free( mcBlockData );
               if ( result != 0 )
               {
                  return (DRX_STS_ERROR);
               };
            };
            break;

         /*===================================================================*/
         default:
            return DRX_STS_INVALID_ARG;
            break;

      } /* switch ( action ) */


      /* Next block */
      mcData += mcBlockNrBytes;

   } /* for( i = 0 ; i<mcNrOfBlks ; i++ ) */

   return (DRX_STS_OK);
}

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

/**
* \fn DRXStatus_t CtrlVersion()
* \brief Build list of version information.
* \param demod A pointer to a demodulator instance.
* \param versionList Pointer to pinter of linked list of versions.
* \return DRXStatus_t.
*/
static DRXStatus_t
CtrlVersion( pDRXDemodInstance_t demod,
             pDRXVersionList_t   *versionList )
{
   static char drxDriverCoreModuleName[]  = "DriverCoreModule";
   static char drxDriverCoreVersionText[] =
         DRX_VERSIONSTRING( VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH );

   static DRXVersion_t drxDriverCoreVersion = {
      DRX_MODULE_DRIVERCORE,      /**< type identifier of the module */
      drxDriverCoreModuleName,    /**< name or description of module */
      VERSION_MAJOR,              /**< major version number */
      VERSION_MINOR,              /**< minor version number */
      VERSION_PATCH,              /**< patch version number */

⌨️ 快捷键说明

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