📄 mt_spuravoid.c
字号:
/********************************************************************************* Name: mt_spuravoid.c**** Copyright 2006-2008 Microtune, Inc. All Rights Reserved**** This source code file contains confidential information and/or trade** secrets of Microtune, Inc. or its affiliates and is subject to the** terms of your confidentiality agreement with Microtune, Inc. or one of** its affiliates, as applicable.*******************************************************************************//********************************************************************************* Name: mt_spuravoid.c**** Description: Microtune spur avoidance software module.** Supports Microtune tuner drivers.**** CVS ID: $Id: mt_spuravoid.c,v 1.2 2008/03/10 22:03:07 software Exp $** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $**** Revision History:**** SCR Date Author Description** -------------------------------------------------------------------------** 082 03-25-2005 JWS Original multi-tuner support - requires** MTxxxx_CNT declarations** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0.** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid** of compiler warnings** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur** avoidance into a single module.** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range** (f_min, f_max) < 0, ignore the entry.** 115 03-23-2007 DAD Fix declaration of spur due to truncation** errors.** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from** tuner DLL.** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for** multi-tuners that have** (delta IF1) > (f_out-f_outbw/2).** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+)** Added logic to force f_Center within 1/2 f_Step.** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2** Type casts added to preserve correct sign.*******************************************************************************/#include "mt_spuravoid.h"#include <stdlib.h>#include <assert.h> /* debug purposes */#if !defined(MT_TUNER_CNT)#error MT_TUNER_CNT is not defined (see mt_userdef.h)#endif#if MT_TUNER_CNT == 0#error MT_TUNER_CNT must be updated in mt_userdef.h#endif/* Version of this module */#define VERSION 10108 /* Version 01.18 *//* Implement ceiling, floor functions. */#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0))#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))#define ufloor(n, d) ((n)/(d))struct MT_FIFZone_t{ SData_t min_; SData_t max_;};#if MT_TUNER_CNT > 1static MT_AvoidSpursData_t* TunerList[MT_TUNER_CNT];static UData_t TunerCount = 0;#endifUData_t MT_RegisterTuner(MT_AvoidSpursData_t* pAS_Info){#if MT_TUNER_CNT == 1 pAS_Info->nAS_Algorithm = 1; return MT_OK;#else UData_t index; pAS_Info->nAS_Algorithm = 2; /* ** Check to see if tuner is already registered */ for (index = 0; index < TunerCount; index++) { if (TunerList[index] == pAS_Info) { return MT_OK; /* Already here - no problem */ } } /* ** Add tuner to list - if there is room. */ if (TunerCount < MT_TUNER_CNT) { TunerList[TunerCount] = pAS_Info; TunerCount++; return MT_OK; } else return MT_TUNER_CNT_ERR;#endif}void MT_UnRegisterTuner(MT_AvoidSpursData_t* pAS_Info){#if MT_TUNER_CNT == 1 pAS_Info;#else UData_t index; for (index = 0; index < TunerCount; index++) { if (TunerList[index] == pAS_Info) { TunerList[index] = TunerList[--TunerCount]; } }#endif}/*** Reset all exclusion zones.** Add zones to protect the PLL FracN regions near zero*/void MT_ResetExclZones(MT_AvoidSpursData_t* pAS_Info){ UData_t center;#if MT_TUNER_CNT > 1 UData_t index; MT_AvoidSpursData_t* adj;#endif pAS_Info->nZones = 0; /* this clears the used list */ pAS_Info->usedZones = NULL; /* reset ptr */ pAS_Info->freeZones = NULL; /* reset ptr */ center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 + pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in; while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO1_FracN_Avoid) { /* Exclude LO1 FracN */ MT_AddExclZone(pAS_Info, center-pAS_Info->f_LO1_FracN_Avoid, center-1); MT_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO1_FracN_Avoid); center += pAS_Info->f_ref; } center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 - pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out; while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO2_FracN_Avoid) { /* Exclude LO2 FracN */ MT_AddExclZone(pAS_Info, center-pAS_Info->f_LO2_FracN_Avoid, center-1); MT_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO2_FracN_Avoid); center += pAS_Info->f_ref; }#if MT_TUNER_CNT > 1 /* ** Iterate through all adjacent tuners and exclude frequencies related to them */ for (index = 0; index < TunerCount; ++index) { adj = TunerList[index]; if (pAS_Info == adj) /* skip over our own data, don't process it */ continue; /* ** Add 1st IF exclusion zone covering adjacent tuner's LO2 ** at "adjfLO2 + f_out" +/- m_MinLOSpacing */ if (adj->f_LO2 != 0) MT_AddExclZone(pAS_Info, (adj->f_LO2 + pAS_Info->f_out) - pAS_Info->f_min_LO_Separation, (adj->f_LO2 + pAS_Info->f_out) + pAS_Info->f_min_LO_Separation ); /* ** Add 1st IF exclusion zone covering adjacent tuner's LO1 ** at "adjfLO1 - f_in" +/- m_MinLOSpacing */ if (adj->f_LO1 != 0) MT_AddExclZone(pAS_Info, (adj->f_LO1 - pAS_Info->f_in) - pAS_Info->f_min_LO_Separation, (adj->f_LO1 - pAS_Info->f_in) + pAS_Info->f_min_LO_Separation ); }#endif}static struct MT_ExclZone_t* InsertNode(MT_AvoidSpursData_t* pAS_Info, struct MT_ExclZone_t* pPrevNode){ struct MT_ExclZone_t* pNode; /* Check for a node in the free list */ if (pAS_Info->freeZones != NULL) { /* Use one from the free list */ pNode = pAS_Info->freeZones; pAS_Info->freeZones = pNode->next_; } else { /* Grab a node from the array */ pNode = &pAS_Info->MT_ExclZones[pAS_Info->nZones]; } if (pPrevNode != NULL) { pNode->next_ = pPrevNode->next_; pPrevNode->next_ = pNode; } else /* insert at the beginning of the list */ { pNode->next_ = pAS_Info->usedZones; pAS_Info->usedZones = pNode; } pAS_Info->nZones++; return pNode;}static struct MT_ExclZone_t* RemoveNode(MT_AvoidSpursData_t* pAS_Info, struct MT_ExclZone_t* pPrevNode, struct MT_ExclZone_t* pNodeToRemove){ struct MT_ExclZone_t* pNext = pNodeToRemove->next_; /* Make previous node point to the subsequent node */ if (pPrevNode != NULL) pPrevNode->next_ = pNext; /* Add pNodeToRemove to the beginning of the freeZones */ pNodeToRemove->next_ = pAS_Info->freeZones; pAS_Info->freeZones = pNodeToRemove; /* Decrement node count */ pAS_Info->nZones--; return pNext;}/********************************************************************************* Name: MT_AddExclZone**** Description: Add (and merge) an exclusion zone into the list.** If the range (f_min, f_max) is totally outside the** 1st IF BW, ignore the entry.** If the range (f_min, f_max) is negative, ignore the entry.**** Revision History:**** SCR Date Author Description** -------------------------------------------------------------------------** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range** (f_min, f_max) < 0, ignore the entry.*******************************************************************************/void MT_AddExclZone(MT_AvoidSpursData_t* pAS_Info, UData_t f_min, UData_t f_max){ /* Check to see if this overlaps the 1st IF filter */ if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) && (f_min < f_max)) { /* ** 1 2 3 4 5 6 ** ** New entry: |---| |--| |--| |-| |---| |--| ** or or or or or ** Existing: |--| |--| |--| |---| |-| |--| */ struct MT_ExclZone_t* pNode = pAS_Info->usedZones; struct MT_ExclZone_t* pPrev = NULL; struct MT_ExclZone_t* pNext = NULL; /* Check for our place in the list */ while ((pNode != NULL) && (pNode->max_ < f_min)) { pPrev = pNode; pNode = pNode->next_; } if ((pNode != NULL) && (pNode->min_ < f_max)) { /* Combine me with pNode */ if (f_min < pNode->min_) pNode->min_ = f_min; if (f_max > pNode->max_) pNode->max_ = f_max; } else { pNode = InsertNode(pAS_Info, pPrev); pNode->min_ = f_min; pNode->max_ = f_max; } /* Look for merging possibilities */ pNext = pNode->next_; while ((pNext != NULL) && (pNext->min_ < pNode->max_)) { if (pNext->max_ > pNode->max_) pNode->max_ = pNext->max_; pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ } }}/********************************************************************************* Name: MT_ChooseFirstIF**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -