📄 drx_driver.c
字号:
/**
* \file $Id: drx_driver.c,v 1.16 2005/11/07 10:15:29 paulja Exp $
*
* \brief Generic DRX functionality, DRX driver core.
*
* \author Paul Janssen
*/
/*
* $(c) 2004-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 "drx_driver.h"
#include "drx_driver_version.h"
#include "bsp_host.h"
/*-----------------------------------------------------------------------------
DEFINES
----------------------------------------------------------------------------*/
/*============================================================================*/
/*=== MICROCODE RELATED DEFINES ==============================================*/
/*============================================================================*/
/**
* \def UCODE_MAGIC_WORD
* \brief Magic word for checking correct Endianess of microcode data.
*
*/
#define UCODE_MAGIC_WORD ((((char)'H')<<8)+((char)'L'))
/**
* \def UCODE_CRC_FLAG
* \brief CRC flag in ucode header, flags field.
*
*/
#define UCODE_CRC_FLAG (0x0001)
/**
* \def UCODE_COMPRESSION_FLAG
* \brief Compression flag in ucode header, flags field.
*
*/
#define UCODE_COMPRESSION_FLAG (0x0002)
/*============================================================================*/
/*=== CHANNEL SCAN RELATED DEFINES ===========================================*/
/*============================================================================*/
/**
* \def DRX_SCAN_MAX_PROGRESS
* \brief Maximum progress indication.
*
* Progress indication will run from 0 upto DRX_SCAN_MAX_PROGRESS during scan.
*
*/
#define DRX_SCAN_MAX_PROGRESS 1000
/**
* \def DRX_SCAN_8MHZ_STEP
* \brief Distance in kHz between two centre frequencies in 8Mhz grid
*/
#define DRX_SCAN_8MHZ_STEP 8000
/**
* \def DRX_SCAN_7MHZ_STEP
* \brief Distance in kHz between two centre frequencies in 7Mhz grid
*/
#define DRX_SCAN_7MHZ_STEP 7000
/**
* \def DRX_SCAN_6MHZ_STEP
* \brief Distance in kHz between two centre frequencies in 6Mhz grid
*/
#define DRX_SCAN_6MHZ_STEP 6000
/*-----------------------------------------------------------------------------
GLOBAL VARIABLES
----------------------------------------------------------------------------*/
/*============================================================================*/
/*============================================================================*/
/*== Instance administration =================================================*/
/*============================================================================*/
/*============================================================================*/
/* NULL terminated array of pointer to demod instance controled by driver. */
static pDRXDemodInstance_t *drxDriverDemodsInstancesList = NULL;
/*-----------------------------------------------------------------------------
STRUCTURES
----------------------------------------------------------------------------*/
typedef struct {
u32_t addr;
u16_t size;
u16_t flags; /* bit[15..2]=reserved,
bit[1]= compression on/off
bit[0]= CRC on/off */
u16_t CRC;
} DRXUCodeBlockHdr_t, *pDRXUCodeBlockHdr_t;
/*-----------------------------------------------------------------------------
FUNCTIONS
----------------------------------------------------------------------------*/
/*============================================================================*/
/*============================================================================*/
/*== Channel Scan Functions ==================================================*/
/*============================================================================*/
/*============================================================================*/
/**
* \fn DRXStatus_t ScanWaitForLock()
* \brief Wait for lock while scanning.
* \param demod Pointer to demodulator instance.
* \param lockStat Pointer to bool indicating if end result is lock or not.
* \return DRXStatus_t.
*
* Wait until timeout, DEMOD_LOCK or NEVER_LOCK.
*
* Assume lock function returns : at least DRX_NOT_LOCKED and DRX_DEMOD_LOCK.
* In case DRX_NEVER_LOCK is returned the poll-wait will be aborted.
*
* Assume BSP has a clock function to retreive a millisecond ticker value.
*
*/
static DRXStatus_t
ScanWaitForLock( pDRXDemodInstance_t demod,
pBool_t isLocked )
{
Bool_t doneWaiting = FALSE;
DRXLockStatus_t lockState = DRX_NOT_LOCKED;
DRXLockStatus_t desiredLockState = DRX_NOT_LOCKED;
u32_t timeoutValue = 0;
u32_t startTimeLockStage = 0;
u32_t currentTime = 0;
u32_t timerValue = 0;
/* Check arguments */
if ( isLocked == NULL )
{
return ( DRX_STS_INVALID_ARG);
}
*isLocked = FALSE;
timeoutValue = (u32_t) demod->myCommonAttr->scanDemodLockTimeout;
desiredLockState = demod->myCommonAttr->scanDesiredLock;
startTimeLockStage=DRXBSP_HST_Clock();
/* Start polling loop, checking for lock & timeout */
while ( doneWaiting == FALSE ) {
if ( DRX_Ctrl( demod, DRX_CTRL_LOCK_STATUS, &lockState ) != DRX_STS_OK )
{
return (DRX_STS_ERROR);
}
currentTime=DRXBSP_HST_Clock();
/* Check for time out in this lock stage */
timerValue = currentTime - startTimeLockStage;
if ( timerValue > timeoutValue )
{
/* Maximum timeout for this lock stage reached, return no_lock */
doneWaiting = TRUE;
}
else
{
if ( lockState >= desiredLockState )
{
*isLocked = TRUE;
doneWaiting = TRUE;
}
else if ( lockState == DRX_NEVER_LOCK )
{
doneWaiting = TRUE;
} /* if ( lockState != oldLockState ) .. */
} /* if ( timerValue > timeoutValue ) */
} /* while */
return (DRX_STS_OK);
}
/*============================================================================*/
/**
* \fn DRXStatus_t ScanPrepareNextScan()
* \brief Determine next frequency to scan.
* \param demod Pointer to demodulator instance.
* \return DRXStatus_t.
* \retval DRX_STS_OK Succes.
* \retval DRX_STS_ERROR Something went wrong.
* \retval DRX_STS_INVALID_ARG Invalid frequency plan.
*
* Helper function for CtrlScanNext() function.
* Compute next frequency & index in frequency plan.
* Check if scan is ready.
*
*/
static DRXStatus_t
ScanPrepareNextScan ( pDRXDemodInstance_t demod )
{
pDRXCommonAttr_t commonAttr=NULL;
u16_t tableIndex = 0;
u16_t frequencyPlanSize = 0;
pDRXFrequencyPlan_t frequencyPlan = NULL;
DRXFrequency_t nextFrequency = 0;
DRXFrequency_t frequencyStep = 0;
DRXFrequency_t tunerMinFrequency = 0;
DRXFrequency_t tunerMaxFrequency = 0;
/* Check parameters */
if ( demod ->myCommonAttr->scanParam == NULL)
{
return (DRX_STS_ERROR);
}
commonAttr = (pDRXCommonAttr_t)demod->myCommonAttr;
tableIndex = commonAttr->scanFreqPlanIndex;
frequencyPlan = commonAttr->scanParam->frequencyPlan;
nextFrequency = commonAttr->scanNextFrequency;
tunerMinFrequency = commonAttr->tunerMinFreqRF;
tunerMaxFrequency = commonAttr->tunerMaxFreqRF;
do {
/* Determine frequency step of channel to scan */
switch ( frequencyPlan[tableIndex].bandwidth ) {
case DRX_BANDWIDTH_8MHZ:
frequencyStep = DRX_SCAN_8MHZ_STEP;
break;
case DRX_BANDWIDTH_7MHZ:
frequencyStep = DRX_SCAN_7MHZ_STEP;
break;
case DRX_BANDWIDTH_6MHZ:
frequencyStep = DRX_SCAN_6MHZ_STEP;
break;
default:
/* Frequency plan content is invalid */
return (DRX_STS_INVALID_ARG);
break;
};
/* Search next frequency to scan */
nextFrequency += frequencyStep;
if ( nextFrequency > frequencyPlan[tableIndex].last )
{
/* reached end of this band */
tableIndex++;
frequencyPlanSize = commonAttr->scanParam->frequencyPlanSize;
if ( tableIndex >= frequencyPlanSize )
{
/* reached end of frequency plan */
commonAttr->scanReady = TRUE;
} else {
nextFrequency = frequencyPlan[tableIndex].first;
}
}
if ( nextFrequency > (tunerMaxFrequency) )
{
/* reached end of tuner range */
commonAttr->scanReady = TRUE;
}
} while( ( nextFrequency < tunerMinFrequency ) &&
( commonAttr->scanReady == FALSE ) );
/* Store new values */
commonAttr->scanFreqPlanIndex = tableIndex;
commonAttr->scanNextFrequency = nextFrequency;
return (DRX_STS_OK);
}
/*============================================================================*/
/**
* \fn DRXStatus_t CtrlScanInit()
* \brief Initialize for channel scan.
* \param demod Pointer to demodulator instance.
* \param scanParam Pointer to scan parameters.
* \return DRXStatus_t.
* \retval DRX_STS_OK Initialized for scan.
* \retval DRX_STS_ERROR No overlap between frequency plan and tuner range.
* \retval DRX_STS_INVALID_ARG Wrong parameters.
*
* After calling this routine scanning will start at the first centre frequency
* of the frequency plan that is within the tuner range.
*
*/
static DRXStatus_t
CtrlScanInit( pDRXDemodInstance_t demod,
pDRXScanParam_t scanParam )
{
pDRXCommonAttr_t commonAttr=NULL;
DRXFrequency_t maxTunerFreq = 0;
DRXFrequency_t minTunerFreq = 0;
u16_t nrChannelsInPlan = 0;
u16_t i = 0;
commonAttr = (pDRXCommonAttr_t)demod -> myCommonAttr;
commonAttr->scanActive = TRUE;
/* invalidate a previous SCAN_INIT */
commonAttr->scanParam = NULL;
commonAttr->scanNextFrequency = 0;
/* Check parameters */
if ( ( demod->myTuner == NULL) ||
( scanParam == NULL) ||
( scanParam->numTries == 0) ||
( scanParam->frequencyPlan == NULL) ||
( scanParam->frequencyPlanSize == 0 )
)
{
commonAttr->scanActive = FALSE;
return (DRX_STS_INVALID_ARG);
} /* if */
/* Check frequency plan contents */
maxTunerFreq = commonAttr->tunerMaxFreqRF;
minTunerFreq = commonAttr->tunerMinFreqRF;
for( i = 0; i < (scanParam->frequencyPlanSize); i++ )
{
DRXFrequency_t width = 0;
DRXFrequency_t step = 0;
DRXFrequency_t firstFreq = scanParam->frequencyPlan[i].first;
DRXFrequency_t lastFreq = scanParam->frequencyPlan[i].last;
DRXFrequency_t minFreq = 0;
DRXFrequency_t maxFreq = 0;
if ( firstFreq > lastFreq )
{
/* First centre frequency is higher then last centre frequency */
commonAttr->scanActive = FALSE;
return (DRX_STS_INVALID_ARG);
} /* if */
width = lastFreq - firstFreq;
switch ( scanParam->frequencyPlan[i].bandwidth ) {
case DRX_BANDWIDTH_6MHZ:
step = DRX_SCAN_6MHZ_STEP;
break;
case DRX_BANDWIDTH_7MHZ:
step = DRX_SCAN_7MHZ_STEP;
break;
case DRX_BANDWIDTH_8MHZ:
step = DRX_SCAN_8MHZ_STEP;
break;
default:
/* Invalid bandwidth parameter in frequency plan */
commonAttr->scanActive = FALSE;
return (DRX_STS_INVALID_ARG);
break;
}; /* switch */
if ( (width % step) != 0 )
{
/* Difference between last and first centre frequency is not
an integer number of bandwidths */
commonAttr->scanActive = FALSE;
return (DRX_STS_INVALID_ARG);
} /* if */
/* Check if frequency plan entry intersects with tuner range */
if ( lastFreq >= minTunerFreq )
{
if ( firstFreq <= maxTunerFreq )
{
if ( firstFreq >= minTunerFreq )
{
minFreq = firstFreq;
} else {
u32_t n=0;
n=( minTunerFreq - firstFreq )/step;
if ( (( minTunerFreq - firstFreq )%step) != 0 )
{
n++;
}
minFreq = firstFreq + n*step;
}
if ( lastFreq <= maxTunerFreq )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -