📄 drx_driver.c
字号:
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 + -