Fork of my original MQTTGateway

Dependencies:   mbed-http

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPIRIT_Radio.c Source File

SPIRIT_Radio.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    SPIRIT_Radio.c
00004   * @author  VMA division - AMS
00005   * @version 3.2.2
00006   * @date    08-July-2015
00007   * @brief   This file provides all the low level API to manage Analog and Digital
00008   *          radio part of SPIRIT.
00009   * @details
00010   *
00011   * @attention
00012   *
00013   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00014   *
00015   * Redistribution and use in source and binary forms, with or without modification,
00016   * are permitted provided that the following conditions are met:
00017   *   1. Redistributions of source code must retain the above copyright notice,
00018   *      this list of conditions and the following disclaimer.
00019   *   2. Redistributions in binary form must reproduce the above copyright notice,
00020   *      this list of conditions and the following disclaimer in the documentation
00021   *      and/or other materials provided with the distribution.
00022   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00023   *      may be used to endorse or promote products derived from this software
00024   *      without specific prior written permission.
00025   *
00026   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00029   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00030   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00032   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00033   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00034   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036   *
00037   ******************************************************************************
00038   */
00039 
00040 /* Includes ------------------------------------------------------------------*/
00041 #include "SPIRIT_Radio.h"
00042 #include "MCU_Interface.h"
00043 #include <math.h>
00044 
00045 /** @addtogroup SPIRIT_Libraries
00046 * @{
00047 */
00048 
00049 
00050 /** @addtogroup SPIRIT_Radio
00051 * @{
00052 */
00053 
00054 
00055 /** @defgroup Radio_Private_TypesDefinitions            Radio Private Types Definitions
00056 * @{
00057 */
00058 
00059 
00060 /**
00061 * @}
00062 */
00063 
00064 
00065 /** @defgroup Radio_Private_Defines                     Radio Private Defines
00066 * @{
00067 */
00068 
00069 
00070 
00071 
00072 /**
00073 * @}
00074 */
00075 
00076 
00077 /** @defgroup Radio_Private_Macros                      Radio Private Macros
00078 * @{
00079 */
00080 #define XTAL_FLAG(xtalFrequency)               (xtalFrequency>=25e6) ? XTAL_FLAG_26_MHz:XTAL_FLAG_24_MHz
00081 
00082 #define ROUND(A)                                  (((A-(uint32_t)A)> 0.5)? (uint32_t)A+1:(uint32_t)A)
00083 /**
00084 * @}
00085 */
00086 
00087 
00088 /** @defgroup Radio_Private_Variables                   Radio Private Variables
00089 * @{
00090 */
00091 /**
00092 * @brief  The Xtal frequency. To be set by the user (see SetXtalFreq() function)
00093 */
00094 static uint32_t s_lXtalFrequency;
00095 
00096 /**
00097 * @brief  Factor is: B/2 used in the formula for SYNTH word calculation
00098 */
00099 static const uint8_t s_vectcBHalfFactor[4]={(HIGH_BAND_FACTOR/2), (MIDDLE_BAND_FACTOR/2), (LOW_BAND_FACTOR/2), (VERY_LOW_BAND_FACTOR/2)};
00100 
00101 /**
00102 * @brief  BS value to write in the SYNT0 register according to the selected band
00103 */
00104 static const uint8_t s_vectcBandRegValue[4]={SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32};
00105 
00106 
00107 /**
00108 * @brief  It represents the available channel bandwidth times 10 for 26 Mhz xtal.
00109 * @note   The channel bandwidth for others xtal frequencies can be computed since this table
00110 *         multiplying the current table by a factor xtal_frequency/26e6.
00111 */
00112 static const uint16_t s_vectnBandwidth26M[90]=
00113 {
00114   8001, 7951, 7684, 7368, 7051, 6709, 6423, 5867, 5414, \
00115     4509, 4259, 4032, 3808, 3621, 3417, 3254, 2945, 2703, \
00116       2247, 2124, 2015, 1900, 1807, 1706, 1624, 1471, 1350, \
00117         1123, 1062, 1005,  950,  903,  853,  812,  735,  675, \
00118           561,  530,  502,  474,  451,  426,  406,  367,  337, \
00119             280,  265,  251,  237,  226,  213,  203,  184,  169, \
00120               140,  133,  126,  119,  113,  106,  101,   92,   84, \
00121                 70,   66,   63,   59,   56,   53,   51,   46,   42, \
00122                   35,   33,   31,   30,   28,   27,   25,   23,   21, \
00123                     18,   17,   16,   15,   14,   13,   13,   12,   11
00124 };
00125 
00126 /**
00127 * @brief  It represents the available VCO frequencies
00128 */
00129 static const uint16_t s_vectnVCOFreq[16]=
00130 {
00131   4644, 4708, 4772, 4836, 4902, 4966, 5030, 5095, \
00132     5161, 5232, 5303, 5375, 5448, 5519, 5592, 5663
00133 };
00134 
00135 /**
00136 * @brief  This variable is used to enable or disable
00137 *  the VCO calibration WA called at the end of the SpiritRadioSetFrequencyBase fcn.
00138 *  Default is enabled.
00139 */
00140 static SpiritFunctionalState xDoVcoCalibrationWA=S_ENABLE;
00141 
00142 
00143 /**
00144 * @brief  These values are used to interpolate the power curves.
00145 *         Interpolation curves are linear in the following 3 regions:
00146 *       - reg value: 1 to 13    (up region)
00147 *       - reg value: 13 to 40   (mid region)
00148 *       - reg value: 41 to 90   (low region)
00149 *       power_reg = m*power_dBm + q
00150 *       For each band the order is: {m-up, q-up, m-mid, q-mid, m-low, q-low}.
00151 * @note The power interpolation curves have been extracted
00152 *       by measurements done on the divisional evaluation boards.
00153 */
00154 static const float fPowerFactors[5][6]={ 
00155   {-2.11,25.66,-2.11,25.66,-2.00,31.28},   /* 915 */
00156   {-2.04,23.45,-2.04,23.45,-1.95,27.66},   /* 868 */
00157   {-3.48,38.45,-1.89,27.66,-1.92,30.23},   /* 433 */
00158   {-3.27,35.43,-1.80,26.31,-1.89,29.61},   /* 315 */
00159   {-4.18,50.66,-1.80,30.04,-1.86,32.22},   /* 169 */
00160 };
00161 
00162 /**
00163 * @}
00164 */
00165 
00166 
00167 /** @defgroup Radio_Private_FunctionPrototypes          Radio Private Function Prototypes
00168 * @{
00169 */
00170 
00171 
00172 /**
00173 * @}
00174 */
00175 
00176 
00177 /** @defgroup Radio_Private_Functions                    Radio Private Functions
00178 * @{
00179 */
00180 
00181 /**
00182 * @brief  Initializes the SPIRIT analog and digital radio part according to the specified
00183 *         parameters in the pxSRadioInitStruct.
00184 * @param  pxSRadioInitStruct pointer to a SRadioInit structure that
00185 *         contains the configuration information for the analog radio part of SPIRIT.
00186 * @retval Error code: 0=no error, 1=error during calibration of VCO.
00187 */
00188 uint8_t SpiritRadioInit(SRadioInit* pxSRadioInitStruct)
00189 {
00190   int32_t FOffsetTmp;
00191   uint8_t anaRadioRegArray[8], digRadioRegArray[4];
00192   int16_t xtalOffsetFactor;
00193   uint8_t drM, drE, FdevM, FdevE, bwM, bwE;
00194     
00195   /* Workaround for Vtune */
00196   uint8_t value = 0xA0; SpiritSpiWriteRegisters(0x9F, 1, &value);
00197   
00198   /* Calculates the offset respect to RF frequency and according to xtal_ppm parameter: (xtal_ppm*FBase)/10^6 */
00199   FOffsetTmp = (int32_t)(((float)pxSRadioInitStruct->nXtalOffsetPpm *pxSRadioInitStruct->lFrequencyBase )/PPM_FACTOR);
00200   
00201   /* Check the parameters */
00202   s_assert_param(IS_FREQUENCY_BAND(pxSRadioInitStruct->lFrequencyBase ));
00203   s_assert_param(IS_MODULATION_SELECTED(pxSRadioInitStruct->xModulationSelect ));
00204   s_assert_param(IS_DATARATE(pxSRadioInitStruct->lDatarate ));
00205   s_assert_param(IS_FREQUENCY_OFFSET(FOffsetTmp,s_lXtalFrequency));
00206   s_assert_param(IS_CHANNEL_SPACE(pxSRadioInitStruct->nChannelSpace ,s_lXtalFrequency));
00207   s_assert_param(IS_F_DEV(pxSRadioInitStruct->lFreqDev ,s_lXtalFrequency));
00208   
00209   /* Disable the digital, ADC, SMPS reference clock divider if fXO>24MHz or fXO<26MHz */
00210   SpiritSpiCommandStrobes(COMMAND_STANDBY);    
00211   do{
00212     /* Delay for state transition */
00213     for(volatile uint8_t i=0; i!=0xFF; i++);
00214     
00215     /* Reads the MC_STATUS register */
00216     SpiritRefreshStatus();
00217   }while(g_xStatus.MC_STATE!=MC_STATE_STANDBY);
00218   
00219   if(s_lXtalFrequency<DOUBLE_XTAL_THR)
00220   {
00221     SpiritRadioSetDigDiv(S_DISABLE);
00222     s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth ,s_lXtalFrequency));
00223   }
00224   else
00225   {      
00226     SpiritRadioSetDigDiv(S_ENABLE);
00227     s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth ,(s_lXtalFrequency>>1)));
00228   }
00229   
00230   /* Goes in READY state */
00231   SpiritSpiCommandStrobes(COMMAND_READY);
00232   do{
00233     /* Delay for state transition */
00234     for(volatile uint8_t i=0; i!=0xFF; i++);
00235     
00236     /* Reads the MC_STATUS register */
00237     SpiritRefreshStatus();
00238   }while(g_xStatus.MC_STATE!=MC_STATE_READY);
00239   
00240   /* Calculates the FC_OFFSET parameter and cast as signed int: FOffsetTmp = (Fxtal/2^18)*FC_OFFSET */
00241   xtalOffsetFactor = (int16_t)(((float)FOffsetTmp*FBASE_DIVIDER)/s_lXtalFrequency);
00242   anaRadioRegArray[2] = (uint8_t)((((uint16_t)xtalOffsetFactor)>>8)&0x0F);
00243   anaRadioRegArray[3] = (uint8_t)(xtalOffsetFactor);
00244   
00245   /* Calculates the channel space factor */
00246   anaRadioRegArray[0] =((uint32_t)pxSRadioInitStruct->nChannelSpace <<9)/(s_lXtalFrequency>>6)+1;
00247   
00248   SpiritManagementWaTRxFcMem(pxSRadioInitStruct->lFrequencyBase );
00249   
00250   /* 2nd order DEM algorithm enabling */
00251   uint8_t tmpreg; SpiritSpiReadRegisters(0xA3, 1, &tmpreg);
00252   tmpreg &= ~0x02; SpiritSpiWriteRegisters(0xA3, 1, &tmpreg);
00253   
00254   /* Check the channel center frequency is in one of the possible range */
00255   s_assert_param(IS_FREQUENCY_BAND((pxSRadioInitStruct->lFrequencyBase  + ((xtalOffsetFactor*s_lXtalFrequency)/FBASE_DIVIDER) + pxSRadioInitStruct->nChannelSpace  * pxSRadioInitStruct->cChannelNumber )));  
00256   
00257   /* Calculates the datarate mantissa and exponent */
00258   SpiritRadioSearchDatarateME(pxSRadioInitStruct->lDatarate , &drM, &drE);
00259   digRadioRegArray[0] = (uint8_t)(drM);
00260   digRadioRegArray[1] = (uint8_t)(0x00 | pxSRadioInitStruct->xModulationSelect  |drE);
00261   
00262   /* Read the fdev register to preserve the clock recovery algo bit */
00263   SpiritSpiReadRegisters(0x1C, 1, &tmpreg);
00264   
00265   /* Calculates the frequency deviation mantissa and exponent */
00266   SpiritRadioSearchFreqDevME(pxSRadioInitStruct->lFreqDev , &FdevM, &FdevE);
00267   digRadioRegArray[2] = (uint8_t)((FdevE<<4) | (tmpreg&0x08) | FdevM);
00268   
00269   /* Calculates the channel filter mantissa and exponent */
00270   SpiritRadioSearchChannelBwME(pxSRadioInitStruct->lBandwidth , &bwM, &bwE);
00271   
00272   digRadioRegArray[3] = (uint8_t)((bwM<<4) | bwE);
00273  
00274   float if_off=(3.0*480140)/(s_lXtalFrequency>>12)-64;
00275   
00276   uint8_t ifOffsetAna = ROUND(if_off);
00277   
00278   if(s_lXtalFrequency<DOUBLE_XTAL_THR)
00279   {
00280     /* if offset digital is the same in case of single xtal */
00281     anaRadioRegArray[1] = ifOffsetAna;
00282   }
00283   else
00284   {
00285     if_off=(3.0*480140)/(s_lXtalFrequency>>13)-64;
00286     
00287     /* ... otherwise recompute it */
00288     anaRadioRegArray[1] = ROUND(if_off);
00289   }
00290 //  if(s_lXtalFrequency==24000000) {
00291 //    ifOffsetAna = 0xB6;
00292 //    anaRadioRegArray[1] = 0xB6;
00293 //  }
00294 //  if(s_lXtalFrequency==25000000) {
00295 //    ifOffsetAna = 0xAC;
00296 //    anaRadioRegArray[1] = 0xAC;
00297 //  }
00298 //  if(s_lXtalFrequency==26000000) {
00299 //    ifOffsetAna = 0xA3;
00300 //    anaRadioRegArray[1] = 0xA3;
00301 //  }
00302 //  if(s_lXtalFrequency==48000000) {
00303 //    ifOffsetAna = 0x3B;
00304 //    anaRadioRegArray[1] = 0xB6;
00305 //  }
00306 //  if(s_lXtalFrequency==50000000) {
00307 //    ifOffsetAna = 0x36;
00308 //    anaRadioRegArray[1] = 0xAC;
00309 //  }
00310 //  if(s_lXtalFrequency==52000000) {
00311 //    ifOffsetAna = 0x31;
00312 //    anaRadioRegArray[1] = 0xA3;
00313 //  }
00314   
00315   g_xStatus = SpiritSpiWriteRegisters(IF_OFFSET_ANA_BASE, 1, &ifOffsetAna);
00316 
00317   
00318   /* Sets Xtal configuration */
00319   if(s_lXtalFrequency>DOUBLE_XTAL_THR)
00320   {
00321     SpiritRadioSetXtalFlag(XTAL_FLAG((s_lXtalFrequency/2)));
00322   }
00323   else
00324   {
00325     SpiritRadioSetXtalFlag(XTAL_FLAG(s_lXtalFrequency));
00326   }
00327   
00328   /* Sets the channel number in the corresponding register */
00329   SpiritSpiWriteRegisters(CHNUM_BASE, 1, &pxSRadioInitStruct->cChannelNumber );
00330   
00331   /* Configures the Analog Radio registers */
00332   SpiritSpiWriteRegisters(CHSPACE_BASE, 4, anaRadioRegArray);
00333   
00334   /* Configures the Digital Radio registers */
00335   g_xStatus = SpiritSpiWriteRegisters(MOD1_BASE, 4, digRadioRegArray);
00336   
00337   /* Enable the freeze option of the AFC on the SYNC word */
00338   SpiritRadioAFCFreezeOnSync(S_ENABLE);
00339   
00340   /* Set the IQC correction optimal value */
00341   anaRadioRegArray[0]=0x80;
00342   anaRadioRegArray[1]=0xE3;
00343   g_xStatus = SpiritSpiWriteRegisters(0x99, 2, anaRadioRegArray);
00344   
00345   return SpiritRadioSetFrequencyBase(pxSRadioInitStruct->lFrequencyBase );
00346   
00347 }
00348 
00349 
00350 /**
00351 * @brief  Returns the SPIRIT analog and digital radio structure according to the registers value.
00352 * @param  pxSRadioInitStruct pointer to a SRadioInit structure that
00353 *         contains the configuration information for the analog radio part of SPIRIT.
00354 * @retval None.
00355 */
00356 void SpiritRadioGetInfo(SRadioInit* pxSRadioInitStruct)
00357 {
00358   uint8_t anaRadioRegArray[8], digRadioRegArray[4];
00359   BandSelect band;
00360   int16_t xtalOffsetFactor;
00361   
00362   /* Get the RF board version */
00363   //SpiritVersion xSpiritVersion = SpiritGeneralGetSpiritVersion();
00364   
00365   /* Reads the Analog Radio registers */
00366   SpiritSpiReadRegisters(SYNT3_BASE, 8, anaRadioRegArray);
00367   
00368   /* Reads the Digital Radio registers */
00369   g_xStatus = SpiritSpiReadRegisters(MOD1_BASE, 4, digRadioRegArray);
00370   
00371   /* Reads the operating band masking the Band selected field */
00372   if((anaRadioRegArray[3] & 0x07) == SYNT0_BS_6)
00373   {
00374     band = HIGH_BAND ;
00375   }
00376   else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_12)
00377   {
00378     band = MIDDLE_BAND ;
00379   }
00380   else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_16)
00381   {
00382     band = LOW_BAND ;
00383   }
00384   else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_32)
00385   {
00386     band = VERY_LOW_BAND ;
00387   }
00388   else
00389   {
00390     /* if it is another value, set it to a valid one in order to avoid access violation */
00391     uint8_t tmp=(anaRadioRegArray[3]&0xF8)|SYNT0_BS_6;
00392     SpiritSpiWriteRegisters(SYNT0_BASE,1,&tmp);
00393     band = HIGH_BAND ;
00394   }
00395   
00396   /* Computes the synth word */
00397   uint32_t synthWord = (uint32_t)((((uint32_t)(anaRadioRegArray[0]&0x1F))<<21)+(((uint32_t)(anaRadioRegArray[1]))<<13)+\
00398     (((uint32_t)(anaRadioRegArray[2]))<<5)+(((uint32_t)(anaRadioRegArray[3]))>>3));
00399   
00400   /* Calculates the frequency base */
00401   uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
00402   pxSRadioInitStruct->lFrequencyBase  = (uint32_t)round(synthWord*(((double)s_lXtalFrequency)/(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band])));
00403   
00404   /* Calculates the Offset Factor */
00405   uint16_t xtalOffTemp = ((((uint16_t)anaRadioRegArray[6])<<8)+((uint16_t)anaRadioRegArray[7]));
00406   
00407   /* If a negative number then convert the 12 bit 2-complement in a 16 bit number */
00408   if(xtalOffTemp & 0x0800)
00409   {
00410     xtalOffTemp = xtalOffTemp | 0xF000;
00411   }
00412   else
00413   {
00414     xtalOffTemp = xtalOffTemp & 0x0FFF;
00415   }
00416   
00417   xtalOffsetFactor = *((int16_t*)(&xtalOffTemp));
00418   
00419   /* Calculates the frequency offset in ppm */
00420   pxSRadioInitStruct->nXtalOffsetPpm  =(int16_t)((uint32_t)xtalOffsetFactor*s_lXtalFrequency*PPM_FACTOR)/((uint32_t)FBASE_DIVIDER*pxSRadioInitStruct->lFrequencyBase );
00421   
00422   /* Channel space */
00423   pxSRadioInitStruct->nChannelSpace  = anaRadioRegArray[4]*(s_lXtalFrequency>>15);
00424   
00425   /* Channel number */
00426   pxSRadioInitStruct->cChannelNumber  = SpiritRadioGetChannel();
00427   
00428   /* Modulation select */
00429   pxSRadioInitStruct->xModulationSelect  = (ModulationSelect)(digRadioRegArray[1] & 0x70);
00430   
00431   /* Reads the frequency deviation for mantissa and exponent */
00432   uint8_t FDevM = digRadioRegArray[2]&0x07;
00433   uint8_t FDevE = (digRadioRegArray[2]&0xF0)>>4;
00434   
00435   /* Reads the channel filter register for mantissa and exponent */
00436   uint8_t bwM = (digRadioRegArray[3]&0xF0)>>4;
00437   uint8_t bwE = digRadioRegArray[3]&0x0F;
00438   
00439   uint8_t cDivider = 0;
00440   cDivider = SpiritRadioGetDigDiv();
00441   
00442   /* Calculates the datarate */
00443   pxSRadioInitStruct->lDatarate  = ((s_lXtalFrequency>>(5+cDivider))*(256+digRadioRegArray[0]))>>(23-(digRadioRegArray[1]&0x0F));
00444   
00445   /* Calculates the frequency deviation */
00446   // (((s_lXtalFrequency>>6)*(8+FDevM))>>(12-FDevE+cCorrection));
00447   pxSRadioInitStruct->lFreqDev  =(uint32_t)((float)s_lXtalFrequency/(((uint32_t)1)<<18)*(uint32_t)((8.0+FDevM)/2*(1<<FDevE)));
00448   
00449   /* Reads the channel filter bandwidth from the look-up table and return it */
00450   pxSRadioInitStruct->lBandwidth  = (uint32_t)(100.0*s_vectnBandwidth26M[bwM+(bwE*9)]*((s_lXtalFrequency>>cDivider)/26e6));
00451   
00452 }
00453 
00454 
00455 /**
00456 * @brief  Sets the Xtal configuration in the ANA_FUNC_CONF0 register.
00457 * @param  xXtal one of the possible value of the enum type XtalFrequency.
00458 *         @arg XTAL_FLAG_24_MHz:  in case of 24 MHz crystal
00459 *         @arg XTAL_FLAG_26_MHz:  in case of 26 MHz crystal
00460 * @retval None.
00461 */
00462 void SpiritRadioSetXtalFlag(XtalFlag xXtal)
00463 {
00464   uint8_t tempRegValue = 0x00;
00465   
00466   /* Check the parameters */
00467   s_assert_param(IS_XTAL_FLAG(xXtal));
00468   
00469   /* Reads the ANA_FUNC_CONF_0 register */
00470   g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
00471   if(xXtal == XTAL_FLAG_26_MHz )
00472   {
00473     tempRegValue|=SELECT_24_26_MHZ_MASK;
00474   }
00475   else
00476   {
00477     tempRegValue &= (~SELECT_24_26_MHZ_MASK);
00478   }
00479   
00480   /* Sets the 24_26MHz_SELECT field in the ANA_FUNC_CONF_0 register */
00481   g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
00482   
00483 }
00484 
00485 
00486 /**
00487 * @brief  Returns the Xtal configuration in the ANA_FUNC_CONF0 register.
00488 * @param  None.
00489 * @retval XtalFrequency Settled Xtal configuration.
00490 */
00491 XtalFlag SpiritRadioGetXtalFlag(void)
00492 {
00493   uint8_t tempRegValue;
00494   
00495   /* Reads the Xtal configuration in the ANA_FUNC_CONF_0 register and return the value */
00496   g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
00497   
00498   return (XtalFlag)((tempRegValue & 0x40)>>6);
00499   
00500 }
00501 
00502 
00503 /**
00504 * @brief  Returns the charge pump word for a given VCO frequency.
00505 * @param  lFc channel center frequency expressed in Hz.
00506 *         This parameter can be a value in one of the following ranges:<ul>
00507 *         <li> High_Band: from 779 MHz to 915 MHz </li>
00508 *         <li> Middle Band: from 387 MHz to 470 MHz </li>
00509 *         <li> Low Band: from 300 MHz to 348 MHz </li>
00510 *         <li> Very low Band: from 150 MHz to 174 MHz </li> </ul>
00511 * @retval uint8_t Charge pump word.
00512 */
00513 uint8_t SpiritRadioSearchWCP(uint32_t lFc)
00514 {
00515   int8_t i;
00516   uint32_t vcofreq;
00517   uint8_t BFactor;
00518   
00519   /* Check the channel center frequency is in one of the possible range */
00520   s_assert_param(IS_FREQUENCY_BAND(lFc));
00521   
00522   /* Search the operating band */
00523   if(IS_FREQUENCY_BAND_HIGH(lFc))
00524   {
00525     BFactor = HIGH_BAND_FACTOR;
00526   }
00527   else if(IS_FREQUENCY_BAND_MIDDLE(lFc))
00528   {
00529     BFactor = MIDDLE_BAND_FACTOR;
00530   }
00531   else if(IS_FREQUENCY_BAND_LOW(lFc))
00532   {
00533     BFactor = LOW_BAND_FACTOR;
00534   }
00535   else
00536   {
00537     BFactor = VERY_LOW_BAND_FACTOR;
00538   }
00539   
00540   /* Calculates the VCO frequency VCOFreq = lFc*B */
00541   vcofreq = (lFc/1000000)*BFactor;
00542   
00543   /* Search in the vco frequency array the charge pump word */
00544   if(vcofreq>=s_vectnVCOFreq[15])
00545   {
00546     i=15;
00547   }
00548   else
00549   {
00550     /* Search the value */
00551     for(i=0 ; i<15 && vcofreq>s_vectnVCOFreq[i] ; i++);
00552     
00553     /* Be sure that it is the best approssimation */
00554     if (i!=0 && s_vectnVCOFreq[i]-vcofreq>vcofreq-s_vectnVCOFreq[i-1])
00555       i--;
00556   }
00557   
00558   /* Return index */
00559   return (i%8);
00560   
00561 }
00562 
00563 /**
00564 * @brief  Returns the synth word.
00565 * @param  None.
00566 * @retval uint32_t Synth word.
00567 */
00568 uint32_t SpiritRadioGetSynthWord(void)
00569 {
00570   uint8_t regArray[4];
00571   
00572   /* Reads the SYNTH registers, build the synth word and return it */
00573   g_xStatus = SpiritSpiReadRegisters(SYNT3_BASE, 4, regArray);
00574   return ((((uint32_t)(regArray[0]&0x1F))<<21)+(((uint32_t)(regArray[1]))<<13)+\
00575     (((uint32_t)(regArray[2]))<<5)+(((uint32_t)(regArray[3]))>>3));
00576   
00577 }
00578 
00579 
00580 /**
00581 * @brief  Sets the SYNTH registers.
00582 * @param  lSynthWord the synth word to write in the SYNTH[3:0] registers.
00583 * @retval None.
00584 */
00585 void SpiritRadioSetSynthWord(uint32_t lSynthWord)
00586 {
00587   uint8_t tempArray[4];
00588   uint8_t tempRegValue;
00589   
00590   /* Reads the SYNT0 register */
00591   g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
00592   
00593   /* Mask the Band selected field */
00594   tempRegValue &= 0x07;
00595   
00596   /* Build the array for SYNTH registers */
00597   tempArray[0] = (uint8_t)((lSynthWord>>21)&(0x0000001F));
00598   tempArray[1] = (uint8_t)((lSynthWord>>13)&(0x000000FF));
00599   tempArray[2] = (uint8_t)((lSynthWord>>5)&(0x000000FF));
00600   tempArray[3] = (uint8_t)(((lSynthWord&0x0000001F)<<3)| tempRegValue);
00601   
00602   /* Writes the synth word in the SYNTH registers */
00603   g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, tempArray);
00604   
00605 }
00606 
00607 
00608 /**
00609 * @brief  Sets the operating band.
00610 * @param  xBand the band to set.
00611 *         This parameter can be one of following parameters:
00612 *         @arg  HIGH_BAND   High_Band selected: from 779 MHz to 915 MHz
00613 *         @arg  MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
00614 *         @arg  LOW_BAND:  Low Band selected: from 300 MHz to 348 MHz
00615 *         @arg  VERY_LOW_BAND:  Very low Band selected: from 150 MHz to 174 MHz
00616 * @retval None.
00617 */
00618 void SpiritRadioSetBand(BandSelect xBand)
00619 {
00620   uint8_t tempRegValue;
00621   
00622   /* Check the parameters */
00623   s_assert_param(IS_BAND_SELECTED(xBand));
00624   
00625   /* Reads the SYNT0 register*/
00626   g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
00627   
00628   /* Mask the SYNTH[4;0] field and write the BS value */
00629   tempRegValue &= 0xF8;
00630   tempRegValue |= s_vectcBandRegValue[xBand];
00631   
00632   /* Configures the SYNT0 register setting the operating band */
00633   g_xStatus = SpiritSpiWriteRegisters(SYNT0_BASE, 1, &tempRegValue);
00634   
00635 }
00636 
00637 
00638 /**
00639 * @brief  Returns the operating band.
00640 * @param  None.
00641 * @retval BandSelect Settled band.
00642 *         This returned value can be one of the following parameters:
00643 *         @arg  HIGH_BAND   High_Band selected: from 779 MHz to 915 MHz
00644 *         @arg  MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
00645 *         @arg  LOW_BAND:  Low Band selected: from 300 MHz to 348 MHz
00646 *         @arg  VERY_LOW_BAND:  Very low Band selected: from 150 MHz to 174 MHz
00647 */
00648 BandSelect SpiritRadioGetBand(void)
00649 {
00650   uint8_t tempRegValue;
00651   
00652   /* Reads the SYNT0 register */
00653   g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
00654   
00655   /* Mask the Band selected field */
00656   if((tempRegValue & 0x07) == SYNT0_BS_6)
00657   {
00658     return HIGH_BAND ;
00659   }
00660   else if ((tempRegValue & 0x07) == SYNT0_BS_12)
00661   {
00662     return MIDDLE_BAND ;
00663   }
00664   else if ((tempRegValue & 0x07) == SYNT0_BS_16)
00665   {
00666     return LOW_BAND ;
00667   }
00668   else
00669   {
00670     return VERY_LOW_BAND ;
00671   }
00672   
00673 }
00674 
00675 
00676 /**
00677 * @brief  Sets the channel number.
00678 * @param  cChannel the channel number.
00679 * @retval None.
00680 */
00681 void SpiritRadioSetChannel(uint8_t cChannel)
00682 {
00683   /* Writes the CHNUM register */
00684   g_xStatus = SpiritSpiWriteRegisters(CHNUM_BASE, 1, &cChannel);
00685   
00686 }
00687 
00688 
00689 /**
00690 * @brief  Returns the actual channel number.
00691 * @param  None.
00692 * @retval uint8_t Actual channel number.
00693 */
00694 uint8_t SpiritRadioGetChannel(void)
00695 {
00696   uint8_t tempRegValue;
00697   
00698   /* Reads the CHNUM register and return the value */
00699   g_xStatus = SpiritSpiReadRegisters(CHNUM_BASE, 1, &tempRegValue);
00700   
00701   return tempRegValue;
00702   
00703 }
00704 
00705 
00706 /**
00707 * @brief  Sets the channel space factor in channel space register.
00708 *         The channel spacing step is computed as F_Xo/32768.
00709 * @param  fChannelSpace the channel space expressed in Hz.
00710 * @retval None.
00711 */
00712 void SpiritRadioSetChannelSpace(uint32_t fChannelSpace)
00713 {
00714   uint8_t cChannelSpaceFactor;
00715   
00716   /* Round to the nearest integer */
00717   cChannelSpaceFactor = ((uint32_t)fChannelSpace*CHSPACE_DIVIDER)/s_lXtalFrequency;
00718   
00719   /* Write value into the register */
00720   g_xStatus = SpiritSpiWriteRegisters(CHSPACE_BASE, 1, &cChannelSpaceFactor);
00721   
00722 }
00723 
00724 
00725 /**
00726 * @brief  Returns the channel space register.
00727 * @param  None.
00728 * @retval uint32_t Channel space. The channel space is: CS = channel_space_factor x XtalFrequency/2^15
00729 *         where channel_space_factor is the CHSPACE register value.
00730 */
00731 uint32_t SpiritRadioGetChannelSpace(void)
00732 {
00733   uint8_t channelSpaceFactor;
00734   
00735   /* Reads the CHSPACE register, calculate the channel space and return it */
00736   g_xStatus = SpiritSpiReadRegisters(CHSPACE_BASE, 1, &channelSpaceFactor);
00737   
00738   /* Compute the Hertz value and return it */
00739   return ((channelSpaceFactor*s_lXtalFrequency)/CHSPACE_DIVIDER);
00740   
00741 }
00742 
00743 
00744 /**
00745 * @brief  Sets the FC OFFSET register starting from xtal ppm value.
00746 * @param  nXtalPpm the xtal offset expressed in ppm.
00747 * @retval None.
00748 */
00749 void SpiritRadioSetFrequencyOffsetPpm(int16_t nXtalPpm)
00750 {
00751   uint8_t tempArray[2];
00752   int16_t xtalOffsetFactor;
00753   uint32_t synthWord, fBase;
00754   int32_t FOffsetTmp;
00755   BandSelect band;
00756   
00757   /* Reads the synth word */
00758   synthWord = SpiritRadioGetSynthWord();
00759   
00760   /* Reads the operating band */
00761   band = SpiritRadioGetBand();
00762   
00763   /* Calculates the frequency base */
00764   uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
00765   fBase = synthWord*(s_lXtalFrequency/(s_vectcBHalfFactor[band]*cRefDiv)/FBASE_DIVIDER);
00766   
00767   /* Calculates the offset respect to RF frequency and according to xtal_ppm parameter */
00768   FOffsetTmp = (int32_t)(((float)nXtalPpm*fBase)/PPM_FACTOR);
00769   
00770   /* Check the Offset is in the correct range */
00771   s_assert_param(IS_FREQUENCY_OFFSET(FOffsetTmp,s_lXtalFrequency));
00772   
00773   /* Calculates the FC_OFFSET value to write in the corresponding register */  
00774   xtalOffsetFactor = (int16_t)(((float)FOffsetTmp*FBASE_DIVIDER)/s_lXtalFrequency);
00775   
00776   /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */
00777   tempArray[0]=(uint8_t)((((uint16_t)xtalOffsetFactor)>>8)&0x0F);
00778   tempArray[1]=(uint8_t)(xtalOffsetFactor);
00779   
00780   /* Writes the FC_OFFSET registers */
00781   g_xStatus = SpiritSpiWriteRegisters(FC_OFFSET1_BASE, 2, tempArray);
00782   
00783 }
00784 
00785 
00786 /**
00787 * @brief  Sets the FC OFFSET register starting from frequency offset expressed in Hz.
00788 * @param  lFOffset frequency offset expressed in Hz as signed word.
00789 * @retval None.
00790 */
00791 void SpiritRadioSetFrequencyOffset(int32_t lFOffset)
00792 {
00793   uint8_t tempArray[2];
00794   int16_t offset;
00795   
00796   /* Check that the Offset is in the correct range */
00797   s_assert_param(IS_FREQUENCY_OFFSET(lFOffset,s_lXtalFrequency));
00798   
00799   /* Calculates the offset value to write in the FC_OFFSET register */
00800   offset = (int16_t)(((float)lFOffset*FBASE_DIVIDER)/s_lXtalFrequency);
00801   
00802   /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */
00803   tempArray[0]=(uint8_t)((((uint16_t)offset)>>8)&0x0F);
00804   tempArray[1]=(uint8_t)(offset);
00805   
00806   /* Writes the FC_OFFSET registers */
00807   g_xStatus = SpiritSpiWriteRegisters(FC_OFFSET1_BASE, 2, tempArray);
00808   
00809 }
00810 
00811 
00812 /**
00813 * @brief  Returns the actual frequency offset.
00814 * @param  None.
00815 * @retval int32_t Frequency offset expressed in Hz as signed word.
00816 */
00817 int32_t SpiritRadioGetFrequencyOffset(void)
00818 {
00819   uint8_t tempArray[2];
00820   int16_t xtalOffsetFactor;
00821   
00822   /* Reads the FC_OFFSET registers */
00823   g_xStatus = SpiritSpiReadRegisters(FC_OFFSET1_BASE, 2, tempArray);
00824   
00825   /* Calculates the Offset Factor */
00826   uint16_t xtalOffTemp = ((((uint16_t)tempArray[0])<<8)+((uint16_t)tempArray[1]));
00827   
00828   if(xtalOffTemp & 0x0800)
00829   {
00830     xtalOffTemp = xtalOffTemp | 0xF000;
00831   }
00832   else
00833   {
00834     xtalOffTemp = xtalOffTemp & 0x0FFF;
00835   }
00836   
00837   xtalOffsetFactor = *((int16_t*)(&xtalOffTemp));
00838   
00839   /* Calculates the frequency offset and return it */
00840   return ((int32_t)(xtalOffsetFactor*s_lXtalFrequency)/FBASE_DIVIDER);
00841   
00842 }
00843 
00844 
00845 
00846 /**
00847 * @brief  Sets the Synth word and the Band Select register according to desired base carrier frequency.
00848 *         In this API the Xtal configuration is read out from
00849 *         the corresponding register. The user shall fix it before call this API.
00850 * @param  lFBase the base carrier frequency expressed in Hz as unsigned word.
00851 * @retval Error code: 0=no error, 1=error during calibration of VCO.
00852 */
00853 uint8_t SpiritRadioSetFrequencyBase(uint32_t lFBase)
00854 {
00855   uint32_t synthWord, Fc;
00856   uint8_t band, anaRadioRegArray[4], wcp;
00857   
00858   /* Check the parameter */
00859   s_assert_param(IS_FREQUENCY_BAND(lFBase));
00860   
00861   /* Search the operating band */
00862   if(IS_FREQUENCY_BAND_HIGH(lFBase))
00863   {
00864     band = HIGH_BAND ;
00865   }
00866   else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
00867   {
00868     band = MIDDLE_BAND ;
00869   }
00870   else if(IS_FREQUENCY_BAND_LOW(lFBase))
00871   {
00872     band = LOW_BAND ;
00873   }
00874   else
00875   {
00876     band = VERY_LOW_BAND ;
00877   }
00878   
00879   int32_t FOffset  = SpiritRadioGetFrequencyOffset();
00880   uint32_t lChannelSpace  = SpiritRadioGetChannelSpace();
00881   uint8_t cChannelNum = SpiritRadioGetChannel();
00882   
00883   /* Calculates the channel center frequency */
00884   Fc = lFBase + FOffset + lChannelSpace*cChannelNum;
00885   
00886   /* Reads the reference divider */
00887   uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
00888   
00889   /* Selects the VCO */
00890   switch(band)
00891   {
00892   case VERY_LOW_BAND :
00893     if(Fc<161281250)
00894     {
00895       SpiritCalibrationSelectVco(VCO_L);
00896     }
00897     else
00898     {
00899       SpiritCalibrationSelectVco(VCO_H);
00900     }
00901     break;
00902     
00903   case LOW_BAND :
00904     if(Fc<322562500)
00905     {
00906       SpiritCalibrationSelectVco(VCO_L);
00907     }
00908     else
00909     {
00910       SpiritCalibrationSelectVco(VCO_H);
00911     }
00912     break;
00913     
00914   case MIDDLE_BAND :
00915     if(Fc<430083334)
00916     {
00917       SpiritCalibrationSelectVco(VCO_L);
00918     }
00919     else
00920     {
00921       SpiritCalibrationSelectVco(VCO_H);
00922     }
00923     break;
00924     
00925   case HIGH_BAND :
00926     if(Fc<860166667)
00927     {
00928       SpiritCalibrationSelectVco(VCO_L);
00929     }
00930     else
00931     {
00932       SpiritCalibrationSelectVco(VCO_H);
00933     }
00934   }
00935   
00936   /* Search the VCO charge pump word and set the corresponding register */
00937   wcp = SpiritRadioSearchWCP(Fc);
00938   
00939   synthWord = (uint32_t)(lFBase*s_vectcBHalfFactor[band]*(((double)(FBASE_DIVIDER*cRefDiv))/s_lXtalFrequency));
00940   
00941   /* Build the array of registers values for the analog part */
00942   anaRadioRegArray[0] = (uint8_t)(((synthWord>>21)&(0x0000001F))|(wcp<<5));
00943   anaRadioRegArray[1] = (uint8_t)((synthWord>>13)&(0x000000FF));
00944   anaRadioRegArray[2] = (uint8_t)((synthWord>>5)&(0x000000FF));
00945   anaRadioRegArray[3] = (uint8_t)(((synthWord&0x0000001F)<<3)| s_vectcBandRegValue[band]);
00946   
00947   /* Configures the needed Analog Radio registers */
00948   g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, anaRadioRegArray);
00949   
00950   if(xDoVcoCalibrationWA==S_ENABLE)
00951     return SpiritManagementWaVcoCalibration();
00952   
00953   return 0;
00954 }
00955 
00956 /**
00957 * @brief  To say to the set frequency base if do or not the VCO calibration WA.
00958 * @param  S_ENABLE or S_DISABLE the WA procedure.
00959 * @retval None.
00960 */
00961 void SpiritRadioVcoCalibrationWAFB(SpiritFunctionalState xNewstate)
00962 {
00963   xDoVcoCalibrationWA=xNewstate;
00964 }
00965 
00966 /**
00967 * @brief  Returns the base carrier frequency.
00968 * @param  None.
00969 * @retval uint32_t Base carrier frequency expressed in Hz as unsigned word.
00970 */
00971 uint32_t SpiritRadioGetFrequencyBase(void)
00972 {
00973   uint32_t synthWord;
00974   BandSelect band;
00975   
00976   /* Reads the synth word */
00977   synthWord = SpiritRadioGetSynthWord();
00978   
00979   /* Reads the operating band */
00980   band = SpiritRadioGetBand();
00981   
00982   uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv() + 1;
00983   
00984   /* Calculates the frequency base and return it */
00985   return (uint32_t)round(synthWord*(((double)s_lXtalFrequency)/(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band])));
00986 }
00987 
00988 
00989 /**
00990 * @brief  Returns the actual channel center frequency.
00991 * @param  None.
00992 * @retval uint32_t Actual channel center frequency expressed in Hz.
00993 */
00994 uint32_t SpiritRadioGetCenterFrequency(void)
00995 {
00996   int32_t offset;
00997   uint8_t channel;
00998   uint32_t fBase;
00999   uint32_t channelSpace;
01000   
01001   /* Reads the frequency base */
01002   fBase = SpiritRadioGetFrequencyBase();
01003   
01004   /* Reads the frequency offset */
01005   offset = SpiritRadioGetFrequencyOffset();
01006   
01007   /* Reads the channel space */
01008   channelSpace = SpiritRadioGetChannelSpace();
01009   
01010   /* Reads the channel number */
01011   channel = SpiritRadioGetChannel();
01012   
01013   /* Calculates the channel center frequency and return it */
01014   return (uint32_t)(fBase +  offset + (uint32_t)(channelSpace*channel));
01015   
01016 }
01017 
01018 
01019 /**
01020 * @brief  Returns the mantissa and exponent, whose value used in the datarate formula
01021 *         will give the datarate value closer to the given datarate.
01022 * @param  fDatarate datarate expressed in bps. This parameter ranging between 100 and 500000.
01023 * @param  pcM pointer to the returned mantissa value.
01024 * @param  pcE pointer to the returned exponent value.
01025 * @retval None.
01026 */
01027 void SpiritRadioSearchDatarateME(uint32_t lDatarate, uint8_t* pcM, uint8_t* pcE)
01028 {
01029   volatile SpiritBool find = S_FALSE;
01030   int8_t i=15;
01031   uint8_t cMantissaTmp;
01032   uint8_t cDivider = 0;
01033   
01034   /* Check the parameters */
01035   s_assert_param(IS_DATARATE(lDatarate));
01036   
01037   cDivider = (uint8_t)SpiritRadioGetDigDiv();
01038   
01039   /* Search in the datarate array the exponent value */
01040   while(!find && i>=0)
01041   {
01042     if(lDatarate>=(s_lXtalFrequency>>(20-i+cDivider)))
01043     {
01044       find = S_TRUE;
01045     }
01046     else
01047     {
01048       i--;
01049     }
01050   }
01051   i<0 ? i=0 : i;
01052   *pcE = i;
01053   
01054   /* Calculates the mantissa value according to the datarate formula */
01055   cMantissaTmp = (lDatarate*((uint32_t)1<<(23-i)))/(s_lXtalFrequency>>(5+cDivider))-256;
01056   
01057   /* Finds the mantissa value with less approximation */
01058   int16_t mantissaCalculation[3];
01059   for(uint8_t j=0;j<3;j++)
01060   {
01061     if((cMantissaTmp+j-1))
01062     {
01063       mantissaCalculation[j]=lDatarate-(((256+cMantissaTmp+j-1)*(s_lXtalFrequency>>(5+cDivider)))>>(23-i));
01064     }
01065     else
01066     {
01067       mantissaCalculation[j]=0x7FFF;
01068     }
01069   }
01070   uint16_t mantissaCalculationDelta = 0xFFFF;
01071   for(uint8_t j=0;j<3;j++)
01072   {
01073     if(S_ABS(mantissaCalculation[j])<mantissaCalculationDelta)
01074     {
01075       mantissaCalculationDelta = S_ABS(mantissaCalculation[j]);
01076       *pcM = cMantissaTmp+j-1;
01077     }
01078   }
01079   
01080 }
01081 
01082 
01083 /**
01084 * @brief  Returns the mantissa and exponent for a given bandwidth.
01085 *         Even if it is possible to pass as parameter any value in the below mentioned range,
01086 *         the API will search the closer value according to a fixed table of channel
01087 *         bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, returning the corresponding mantissa
01088 *         and exponent value.
01089 * @param  lBandwidth bandwidth expressed in Hz. This parameter ranging between 1100 and 800100.
01090 * @param  pcM pointer to the returned mantissa value.
01091 * @param  pcE pointer to the returned exponent value.
01092 * @retval None.
01093 */
01094 void SpiritRadioSearchChannelBwME(uint32_t lBandwidth, uint8_t* pcM, uint8_t* pcE)
01095 {
01096   int8_t i, i_tmp;
01097   uint8_t cDivider = 1;
01098   
01099     /* Search in the channel filter bandwidth table the exponent value */
01100   if(SpiritRadioGetDigDiv())
01101   {
01102     cDivider = 2;
01103   }
01104   else
01105   {
01106     cDivider = 1;
01107   }
01108     
01109   s_assert_param(IS_CH_BW(lBandwidth,s_lXtalFrequency/cDivider));
01110   
01111   uint32_t lChfltFactor = (s_lXtalFrequency/cDivider)/100;
01112   
01113   for(i=0;i<90 && (lBandwidth<(uint32_t)((s_vectnBandwidth26M[i]*lChfltFactor)/2600));i++);
01114   
01115   if(i!=0)
01116   {
01117     /* Finds the mantissa value with less approximation */
01118     i_tmp=i;
01119     int16_t chfltCalculation[3];
01120     for(uint8_t j=0;j<3;j++) 
01121     {
01122       if(((i_tmp+j-1)>=0) || ((i_tmp+j-1)<=89))
01123       {
01124         chfltCalculation[j] = lBandwidth - (uint32_t)((s_vectnBandwidth26M[i_tmp+j-1]*lChfltFactor)/2600);
01125       }
01126       else
01127       {
01128         chfltCalculation[j] = 0x7FFF;
01129       }
01130     }
01131     uint16_t chfltDelta = 0xFFFF;
01132     
01133     for(uint8_t j=0;j<3;j++)
01134     {
01135       if(S_ABS(chfltCalculation[j])<chfltDelta)
01136       {
01137         chfltDelta = S_ABS(chfltCalculation[j]);
01138         i=i_tmp+j-1;
01139       }    
01140     }
01141   }
01142   (*pcE) = (uint8_t)(i/9);
01143   (*pcM) = (uint8_t)(i%9);
01144   
01145 }
01146 
01147 /**
01148 * @brief  Returns the mantissa and exponent, whose value used in the frequency deviation formula
01149 *         will give a frequency deviation value most closer to the given frequency deviation.
01150 * @param  fFDev frequency deviation expressed in Hz. This parameter can be a value in the range [F_Xo*8/2^18, F_Xo*7680/2^18].
01151 * @param  pcM pointer to the returned mantissa value.
01152 * @param  pcE pointer to the returned exponent value.
01153 * @retval None.
01154 */
01155 void SpiritRadioSearchFreqDevME(uint32_t lFDev, uint8_t* pcM, uint8_t* pcE)
01156 {
01157   uint8_t i;
01158   uint32_t a,bp,b=0;
01159   float xtalDivtmp=(float)s_lXtalFrequency/(((uint32_t)1)<<18);
01160   
01161   /* Check the parameters */
01162   s_assert_param(IS_F_DEV(lFDev,s_lXtalFrequency));
01163   
01164   for(i=0;i<10;i++)
01165   {
01166     a=(uint32_t)(xtalDivtmp*(uint32_t)(7.5*(1<<i)));
01167     if(lFDev<a)
01168       break;
01169   }
01170   (*pcE) = i;
01171   
01172   for(i=0;i<8;i++)
01173   {
01174     bp=b;
01175     b=(uint32_t)(xtalDivtmp*(uint32_t)((8.0+i)/2*(1<<(*pcE))));
01176     if(lFDev<b)
01177       break;
01178   }
01179   
01180   (*pcM)=i;
01181   if((lFDev-bp)<(b-lFDev))
01182     (*pcM)--;
01183   
01184 }
01185 
01186 
01187 /**
01188 * @brief  Sets the datarate.
01189 * @param  fDatarate datarate expressed in bps. This value shall be in the range
01190 *         [100 500000].
01191 * @retval None.
01192 */
01193 void SpiritRadioSetDatarate(uint32_t lDatarate)
01194 {
01195   uint8_t drE, tempRegValue[2];
01196   
01197   /* Check the parameters */
01198   s_assert_param(IS_DATARATE(lDatarate));
01199   
01200   /* Calculates the datarate mantissa and exponent */
01201   SpiritRadioSearchDatarateME(lDatarate, &tempRegValue[0], &drE);
01202   
01203   /* Reads the MOD_O register*/
01204   SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue[1]);
01205   
01206   /* Mask the other fields and set the datarate exponent */
01207   tempRegValue[1] &= 0xF0;
01208   tempRegValue[1] |= drE;
01209   
01210   /* Writes the Datarate registers */
01211   g_xStatus = SpiritSpiWriteRegisters(MOD1_BASE, 2, tempRegValue);
01212   
01213 }
01214 
01215 
01216 /**
01217 * @brief  Returns the datarate.
01218 * @param  None.
01219 * @retval uint32_t Settled datarate expressed in bps.
01220 */
01221 uint32_t SpiritRadioGetDatarate(void)
01222 {
01223   uint8_t tempRegValue[2];
01224   uint8_t cDivider=0;
01225   
01226   /* Reads the datarate registers for mantissa and exponent */
01227   g_xStatus = SpiritSpiReadRegisters(MOD1_BASE, 2, tempRegValue);
01228   
01229   /* Calculates the datarate */
01230   cDivider = (uint8_t)SpiritRadioGetDigDiv(); 
01231   
01232   return (((s_lXtalFrequency>>(5+cDivider))*(256+tempRegValue[0]))>>(23-(tempRegValue[1]&0x0F)));
01233 }
01234 
01235 
01236 /**
01237 * @brief  Sets the frequency deviation.
01238 * @param  fFDev frequency deviation expressed in Hz. Be sure that this value
01239 *         is in the correct range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz.
01240 * @retval None.
01241 */
01242 void SpiritRadioSetFrequencyDev(uint32_t lFDev)
01243 {
01244   uint8_t FDevM, FDevE, tempRegValue;
01245   
01246   /* Check the parameters */
01247   s_assert_param(IS_F_DEV(lFDev, s_lXtalFrequency));
01248   
01249   /* Calculates the frequency deviation mantissa and exponent */
01250   SpiritRadioSearchFreqDevME(lFDev, &FDevM, &FDevE);
01251   
01252   /* Reads the FDEV0 register */
01253   SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
01254   
01255   /* Mask the other fields and set the frequency deviation mantissa and exponent */
01256   tempRegValue &= 0x08;
01257   tempRegValue |= ((FDevE<<4)|(FDevM));
01258   
01259   /* Writes the Frequency deviation register */
01260   g_xStatus = SpiritSpiWriteRegisters(FDEV0_BASE, 1, &tempRegValue);
01261   
01262 }
01263 
01264 
01265 /**
01266 * @brief  Returns the frequency deviation.
01267 * @param  None.
01268 * @retval uint32_t Frequency deviation value expressed in Hz.
01269 *         This value will be in the range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz.
01270 */
01271 uint32_t SpiritRadioGetFrequencyDev(void)
01272 {
01273   uint8_t tempRegValue, FDevM, FDevE;  
01274 
01275   
01276   /* Reads the frequency deviation register for mantissa and exponent */
01277   g_xStatus = SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
01278   FDevM = tempRegValue&0x07;
01279   FDevE = (tempRegValue&0xF0)>>4;
01280   
01281   /* Calculates the frequency deviation and return it */
01282   //return (((s_lXtalFrequency>>6)*(8+FDevM))>>(13-FDevE));
01283   
01284   return (uint32_t)((float)s_lXtalFrequency/(((uint32_t)1)<<18)*(uint32_t)((8.0+FDevM)/2*(1<<FDevE)));
01285    
01286 }
01287 
01288 
01289 /**
01290 * @brief  Sets the channel filter bandwidth.
01291 * @param  lBandwidth channel filter bandwidth expressed in Hz. This parameter shall be in the range [1100 800100]
01292 *         Even if it is possible to pass as parameter any value in the above mentioned range,
01293 *         the API will search the most closer value according to a fixed table of channel
01294 *         bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet. To verify the settled channel bandwidth
01295 *         it is possible to use the SpiritRadioGetChannelBW() API.
01296 * @retval None.
01297 */
01298 void SpiritRadioSetChannelBW(uint32_t lBandwidth)
01299 {
01300   uint8_t bwM, bwE, tempRegValue;
01301   
01302   /* Search in the channel filter bandwidth table the exponent value */
01303   if(SpiritRadioGetDigDiv())
01304   {
01305     s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency/2)));
01306   }
01307   else
01308   {
01309     s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency)));
01310   } 
01311   
01312   /* Calculates the channel bandwidth mantissa and exponent */
01313   SpiritRadioSearchChannelBwME(lBandwidth, &bwM, &bwE);
01314   tempRegValue = (bwM<<4)|(bwE);
01315   
01316   /* Writes the Channel filter register */
01317   g_xStatus = SpiritSpiWriteRegisters(CHFLT_BASE, 1, &tempRegValue);
01318   
01319 }
01320 
01321 /**
01322 * @brief  Returns the channel filter bandwidth.
01323 * @param  None.
01324 * @retval uint32_t Channel filter bandwidth expressed in Hz.
01325 */
01326 uint32_t SpiritRadioGetChannelBW(void)
01327 {
01328   uint8_t tempRegValue, bwM, bwE;
01329   
01330   /* Reads the channel filter register for mantissa and exponent */
01331   g_xStatus = SpiritSpiReadRegisters(CHFLT_BASE, 1, &tempRegValue);
01332   bwM = (tempRegValue&0xF0)>>4;
01333   bwE = tempRegValue&0x0F;
01334   
01335   /* Reads the channel filter bandwidth from the look-up table and return it */
01336   return (uint32_t)(100.0*s_vectnBandwidth26M[bwM+(bwE*9)]*s_lXtalFrequency/26e6);
01337   
01338 }
01339 
01340 
01341 /**
01342 * @brief  Sets the modulation type.
01343 * @param  xModulation modulation to set.
01344 *         This parameter shall be of type @ref ModulationSelect .
01345 * @retval None.
01346 */
01347 void SpiritRadioSetModulation(ModulationSelect xModulation)
01348 {
01349   uint8_t tempRegValue;
01350   
01351   /* Check the parameters */
01352   s_assert_param(IS_MODULATION_SELECTED(xModulation));
01353   
01354   /* Reads the modulation register */
01355   SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
01356   
01357   /* Mask the other fields and set the modulation type */
01358   tempRegValue &=0x8F;
01359   tempRegValue |= xModulation;
01360   
01361   /* Writes the modulation register */
01362   g_xStatus = SpiritSpiWriteRegisters(MOD0_BASE, 1, &tempRegValue);
01363   
01364 }
01365 
01366 
01367 /**
01368 * @brief  Returns the modulation type used.
01369 * @param  None.
01370 * @retval ModulationSelect Settled modulation type.
01371 */
01372 ModulationSelect SpiritRadioGetModulation(void)
01373 {
01374   uint8_t tempRegValue;
01375   
01376   /* Reads the modulation register MOD0*/
01377   g_xStatus = SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
01378   
01379   /* Return the modulation type */
01380   return (ModulationSelect)(tempRegValue&0x70);
01381   
01382 }
01383 
01384 
01385 /**
01386 * @brief  Enables or Disables the Continuous Wave transmit mode.
01387 * @param  xNewState new state for power ramping.
01388 *         This parameter can be: S_ENABLE or S_DISABLE .
01389 * @retval None.
01390 */
01391 void SpiritRadioCWTransmitMode(SpiritFunctionalState xNewState)
01392 {
01393   uint8_t tempRegValue;
01394   
01395   /* Check the parameters */
01396   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
01397   
01398   /* Reads the modulation register MOD0 and mask the CW field */
01399   SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
01400   if(xNewState == S_ENABLE)
01401   {
01402     tempRegValue |=MOD0_CW;
01403   }
01404   else
01405   {
01406     tempRegValue &= (~MOD0_CW);
01407   }
01408   
01409   /* Writes the new value in the MOD0 register */
01410   g_xStatus = SpiritSpiWriteRegisters(MOD0_BASE, 1, &tempRegValue);
01411   
01412 }
01413 
01414 
01415 /**
01416 * @brief  Sets the OOK Peak Decay.
01417 * @param  xOokDecay Peak decay control for OOK.
01418 *         This parameter shall be of type @ref OokPeakDecay .
01419 * @retval None.
01420 */
01421 void SpiritRadioSetOokPeakDecay(OokPeakDecay xOokDecay)
01422 {
01423   uint8_t tempRegValue;
01424   
01425   /* Check the parameters */
01426   s_assert_param(IS_OOK_PEAK_DECAY(xOokDecay));
01427   
01428   /* Reads the RSSI_FLT register */
01429   SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
01430   
01431   /* Mask the other fields and set OOK Peak Decay */
01432   tempRegValue &= 0xFC;
01433   tempRegValue |= xOokDecay;
01434   
01435   /* Writes the RSSI_FLT register to set the new OOK peak dacay value */
01436   g_xStatus = SpiritSpiWriteRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
01437   
01438 }
01439 
01440 
01441 /**
01442 * @brief  Returns the OOK Peak Decay.
01443 * @param  None
01444 * @retval OokPeakDecay Ook peak decay value.
01445 */
01446 OokPeakDecay SpiritRadioGetOokPeakDecay(void)
01447 {
01448   uint8_t tempRegValue;
01449   
01450   /* Reads the OOK peak decay register RSSI_FLT_BASE*/
01451   g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
01452   
01453   /* Returns the OOK peak decay */
01454   return (OokPeakDecay) (tempRegValue & 0x03);
01455   
01456 }
01457 
01458 /**
01459 * @brief  Returns the PA register value that corresponds to the passed dBm power.
01460 * @param  lFbase Frequency base expressed in Hz.
01461 * @param  fPowerdBm Desired power in dBm.
01462 * @retval Register value as byte.
01463 * @note The power interpolation curves used by this function have been extracted
01464 *       by measurements done on the divisional evaluation boards.
01465 */
01466 uint8_t SpiritRadioGetdBm2Reg(uint32_t lFBase, float fPowerdBm)
01467 {
01468   uint8_t i=0;
01469   uint8_t j=0;
01470   float fReg;
01471   
01472   if(IS_FREQUENCY_BAND_HIGH(lFBase))
01473   {
01474     i=0;
01475     if(lFBase<900000000) i=1;// 868   
01476   }
01477   else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
01478   {
01479     i=2;
01480   }
01481   else if(IS_FREQUENCY_BAND_LOW(lFBase))
01482   {
01483     i=3;
01484   }
01485   else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
01486   {
01487     i=4;
01488   }
01489   
01490   j=1;
01491   if(fPowerdBm>0 && 13.0/fPowerFactors[i][2]-fPowerFactors[i][3]/fPowerFactors[i][2]<fPowerdBm)
01492       j=0;
01493   else if(fPowerdBm<=0 && 40.0/fPowerFactors[i][2]-fPowerFactors[i][3]/fPowerFactors[i][2]>fPowerdBm)
01494       j=2;
01495 
01496   fReg=fPowerFactors[i][2*j]*fPowerdBm+fPowerFactors[i][2*j+1];
01497   
01498   if(fReg<1)
01499     fReg=1;
01500   else if(fReg>90) 
01501     fReg=90;
01502   
01503   return ((uint8_t)fReg);
01504 }
01505 
01506 
01507 /**
01508 * @brief  Returns the dBm power that corresponds to the value of PA register.
01509 * @param  lFbase Frequency base expressed in Hz.
01510 * @param  cPowerReg Register value of the PA.
01511 * @retval Power in dBm as float.
01512 * @note The power interpolation curves used by this function have been extracted
01513 *       by measurements done on the divisional evaluation boards.
01514 */
01515 float SpiritRadioGetReg2dBm(uint32_t lFBase, uint8_t cPowerReg)
01516 {
01517   uint8_t i=0;
01518   uint8_t j=0;
01519   float fPower;
01520   
01521   if(cPowerReg==0 || cPowerReg>90)
01522     return (-130.0);
01523   
01524   if(IS_FREQUENCY_BAND_HIGH(lFBase))
01525   {
01526     i=0;
01527     if(lFBase<900000000) i=1;// 868   
01528   }
01529   else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
01530   {
01531     i=2;
01532   }
01533   else if(IS_FREQUENCY_BAND_LOW(lFBase))
01534   {
01535     i=3;
01536   }
01537   else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
01538   {
01539     i=4;
01540   }
01541   
01542   j=1;
01543   if(cPowerReg<13) j=0;
01544   else if(cPowerReg>40) j=2;
01545   
01546   fPower=(((float)cPowerReg)/fPowerFactors[i][2*j]-fPowerFactors[i][2*j+1]/fPowerFactors[i][2*j]);
01547   
01548   return fPower;
01549 }
01550 
01551 /**
01552 * @brief  Configures the Power Amplifier Table and registers with value expressed in dBm.
01553 * @param  cPALevelMaxIndex number of levels to set. This parameter shall be in the range [0:7].
01554 * @param  cWidth step width expressed in terms of bit period units Tb/8.
01555 *         This parameter shall be in the range [1:4].
01556 * @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
01557 *         @arg LOAD_0_PF    No additional PA load capacitor
01558 *         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
01559 *         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
01560 *         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
01561 * @param  pfPAtabledBm pointer to an array of PA values in dbm between [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dbm.
01562 *         The first element shall be the lower level (PA_LEVEL[0]) value and the last element
01563 *         the higher level one (PA_LEVEL[paLevelMaxIndex]).
01564 * @retval None.
01565 */
01566 void SpiritRadioSetPATabledBm(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, float* pfPAtabledBm)
01567 {
01568   uint8_t palevel[9], address, paLevelValue;
01569   uint32_t lFBase=SpiritRadioGetFrequencyBase();
01570 
01571   /* Check the parameters */
01572   s_assert_param(IS_PA_MAX_INDEX(cPALevelMaxIndex));
01573   s_assert_param(IS_PA_STEP_WIDTH(cWidth));
01574   s_assert_param(IS_PA_LOAD_CAP(xCLoad));
01575   
01576   /* Check the PA level in dBm is in the range and calculate the PA_LEVEL value
01577   to write in the corresponding register using the linearization formula */
01578   for(int i=0; i<=cPALevelMaxIndex; i++)
01579   {
01580     s_assert_param(IS_PAPOWER_DBM(*pfPAtabledBm));
01581     paLevelValue=SpiritRadioGetdBm2Reg(lFBase,(*pfPAtabledBm));
01582     palevel[cPALevelMaxIndex-i]=paLevelValue;
01583     pfPAtabledBm++;
01584   }
01585   
01586   /* Sets the PA_POWER[0] register */
01587   palevel[cPALevelMaxIndex+1]=xCLoad|(cWidth-1)<<3|cPALevelMaxIndex;
01588   
01589   /* Sets the base address */
01590   address=PA_POWER8_BASE+7-cPALevelMaxIndex;
01591   
01592   /* Configures the PA_POWER registers */
01593   g_xStatus = SpiritSpiWriteRegisters(address, cPALevelMaxIndex+2, palevel);
01594   
01595 }
01596 
01597 
01598 /**
01599 * @brief  Returns the Power Amplifier Table and registers, returning values in dBm.
01600 * @param  pcPALevelMaxIndex pointer to the number of levels settled.
01601 *         This parameter will be in the range [0:7].
01602 * @param  pfPAtabledBm pointer to an array of 8 elements containing the PA value in dbm.
01603 *         The first element will be the PA_LEVEL_0 and the last element
01604 *         will be PA_LEVEL_7. Any value higher than PA_UPPER_LIMIT implies no output
01605 *         power (output stage is in high impedance).
01606 * @retval None.
01607 */
01608 void SpiritRadioGetPATabledBm(uint8_t* pcPALevelMaxIndex, float* pfPAtabledBm)
01609 {
01610   uint8_t palevelvect[9];
01611   uint32_t lFBase=SpiritRadioGetFrequencyBase();
01612   
01613   /* Reads the PA_LEVEL_x registers and the PA_POWER_0 register */
01614   g_xStatus = SpiritSpiReadRegisters(PA_POWER8_BASE, 9, palevelvect);
01615   
01616   /* Fill the PAtable */
01617   for(int i=7; i>=0; i--)
01618   {
01619     (*pfPAtabledBm)=SpiritRadioGetReg2dBm(lFBase,palevelvect[i]);
01620     pfPAtabledBm++;
01621   }
01622   
01623   /* Return the settled index */
01624   *pcPALevelMaxIndex = palevelvect[8]&0x07;
01625   
01626 }
01627 
01628 
01629 
01630 
01631 
01632 
01633 /**
01634 * @brief  Sets a specific PA_LEVEL register, with a value given in dBm.
01635 * @param  cIndex PA_LEVEL to set. This parameter shall be in the range [0:7].
01636 * @param  fPowerdBm PA value to write expressed in dBm . Be sure that this values is in the
01637 *         correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm.
01638 * @retval None.
01639 * @note This function makes use of the @ref SpiritRadioGetdBm2Reg fcn to interpolate the 
01640 *       power value.
01641 */
01642 void SpiritRadioSetPALeveldBm(uint8_t cIndex, float fPowerdBm)
01643 {
01644   uint8_t address, paLevelValue;
01645   
01646   /* Check the parameters */
01647   s_assert_param(IS_PA_MAX_INDEX(cIndex));
01648   s_assert_param(IS_PAPOWER_DBM(fPowerdBm));
01649   
01650   /* interpolate the power level */
01651   paLevelValue=SpiritRadioGetdBm2Reg(SpiritRadioGetFrequencyBase(),fPowerdBm);
01652 
01653   /* Sets the base address */
01654   address=PA_POWER8_BASE+7-cIndex;
01655   
01656   /* Configures the PA_LEVEL register */
01657   g_xStatus = SpiritSpiWriteRegisters(address, 1, &paLevelValue);
01658   
01659 }
01660 
01661 
01662 /**
01663 * @brief  Returns a specific PA_LEVEL register, returning a value in dBm.
01664 * @param  cIndex PA_LEVEL to read. This parameter shall be in the range [0:7]
01665 * @retval float Settled power level expressed in dBm. A value
01666 *         higher than PA_UPPER_LIMIT dBm implies no output power
01667 *         (output stage is in high impedance).
01668 * @note This function makes use of the @ref SpiritRadioGetReg2dBm fcn to interpolate the 
01669 *       power value.
01670 */
01671 float SpiritRadioGetPALeveldBm(uint8_t cIndex)
01672 {
01673   uint8_t address, paLevelValue;
01674   
01675   /* Check the parameters */
01676   s_assert_param(IS_PA_MAX_INDEX(cIndex));
01677   
01678   /* Sets the base address */
01679   address=PA_POWER8_BASE+7-cIndex;
01680   
01681   /* Reads the PA_LEVEL[cIndex] register */
01682   g_xStatus = SpiritSpiReadRegisters(address, 1, &paLevelValue);
01683   
01684   return SpiritRadioGetReg2dBm(SpiritRadioGetFrequencyBase(),paLevelValue);
01685 }
01686 
01687 
01688 /**
01689 * @brief  Configures the Power Amplifier Table and registers.
01690 * @param  cPALevelMaxIndex number of levels to set. This parameter shall be in the range [0:7].
01691 * @param  cWidth step width expressed in terms of bit period units Tb/8.
01692 *         This parameter shall be in the range [1:4].
01693 * @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
01694 *         @arg LOAD_0_PF    No additional PA load capacitor
01695 *         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
01696 *         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
01697 *         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
01698 * @param  pcPAtable pointer to an array of PA values in the range [0: 90], where 0 implies no
01699 *         output power, 1 will be the maximum level and 90 the minimum one
01700 *         The first element shall be the lower level (PA_LEVEL[0]) value and the last element
01701 *         the higher level one (PA_LEVEL[paLevelMaxIndex]).
01702 * @retval None.
01703 */
01704 void SpiritRadioSetPATable(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, uint8_t* pcPAtable)
01705 {
01706   uint8_t palevel[9], address;
01707   
01708   /* Check the parameters */
01709   s_assert_param(IS_PA_MAX_INDEX(cPALevelMaxIndex));
01710   s_assert_param(IS_PA_STEP_WIDTH(cWidth));
01711   s_assert_param(IS_PA_LOAD_CAP(xCLoad));
01712   
01713   /* Check the PA levels are in the range */
01714   for(int i=0; i<=cPALevelMaxIndex; i++)
01715   {
01716     s_assert_param(IS_PAPOWER(*pcPAtable));
01717     palevel[cPALevelMaxIndex-i]=*pcPAtable;
01718     pcPAtable++;
01719   }
01720   
01721   /* Sets the PA_POWER[0] register */
01722   palevel[cPALevelMaxIndex+1]=xCLoad|((cWidth-1)<<3)|cPALevelMaxIndex;
01723   
01724   /* Sets the base address */
01725   address=PA_POWER8_BASE+7-cPALevelMaxIndex;
01726   
01727   /* Configures the PA_POWER registers */
01728   g_xStatus = SpiritSpiWriteRegisters(address, cPALevelMaxIndex+2, palevel);
01729   
01730 }
01731 
01732 
01733 /**
01734 * @brief  Returns the Power Amplifier Table and registers.
01735 * @param  pcPALevelMaxIndex pointer to the number of levels settled.
01736 *         This parameter shall be in the range [0:7].
01737 * @param  pcPAtable pointer to an array of 8 elements containing the PA value.
01738 *         The first element will be the PA_LEVEL_0 and the last element
01739 *         will be PA_LEVEL_7. Any value equals to 0 implies that level has
01740 *         no output power (output stage is in high impedance).
01741 * @retval None
01742 */
01743 void SpiritRadioGetPATable(uint8_t* pcPALevelMaxIndex, uint8_t* pcPAtable)
01744 {
01745   uint8_t palevelvect[9];
01746   
01747   /* Reads the PA_LEVEL_x registers and the PA_POWER_0 register */
01748   g_xStatus = SpiritSpiReadRegisters(PA_POWER8_BASE, 9, palevelvect);
01749   
01750   /* Fill the PAtable */
01751   for(int i=7; i>=0; i--)
01752   {
01753     *pcPAtable = palevelvect[i];
01754     pcPAtable++;
01755   }
01756   
01757   /* Return the settled index */
01758   *pcPALevelMaxIndex = palevelvect[8]&0x07;
01759   
01760 }
01761 
01762 
01763 /**
01764 * @brief  Sets a specific PA_LEVEL register.
01765 * @param  cIndex PA_LEVEL to set. This parameter shall be in the range [0:7].
01766 * @param  cPower PA value to write in the register. Be sure that this values is in the
01767 *         correct range [0 : 90].
01768 * @retval None.
01769 */
01770 void SpiritRadioSetPALevel(uint8_t cIndex, uint8_t cPower)
01771 {
01772   uint8_t address;
01773   
01774   /* Check the parameters */
01775   s_assert_param(IS_PA_MAX_INDEX(cIndex));
01776   s_assert_param(IS_PAPOWER(cPower));
01777   
01778   /* Sets the base address */
01779   address=PA_POWER8_BASE+7-cIndex;
01780   
01781   /* Configures the PA_LEVEL register */
01782   g_xStatus = SpiritSpiWriteRegisters(address, 1, &cPower);
01783   
01784 }
01785 
01786 
01787 /**
01788 * @brief  Returns a specific PA_LEVEL register.
01789 * @param  cIndex PA_LEVEL to read. This parameter shall be in the range [0:7].
01790 * @retval uint8_t PA_LEVEL value. A value equal to zero
01791 *         implies no output power (output stage is in high impedance).
01792 */
01793 uint8_t SpiritRadioGetPALevel(uint8_t cIndex)
01794 {
01795   uint8_t address, tempRegValue;
01796   
01797   /* Check the parameters */
01798   s_assert_param(IS_PA_MAX_INDEX(cIndex));
01799   
01800   /* Sets the base address */
01801   address=PA_POWER8_BASE+7-cIndex;
01802   
01803   /* Reads the PA_LEVEL[cIndex] register and return the value */
01804   g_xStatus = SpiritSpiReadRegisters(address, 1, &tempRegValue);
01805   return tempRegValue;
01806   
01807 }
01808 
01809 
01810 /**
01811 * @brief  Sets the output stage additional load capacitor bank.
01812 * @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
01813 *         @arg LOAD_0_PF    No additional PA load capacitor
01814 *         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
01815 *         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
01816 *         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
01817 * @retval None.
01818 */
01819 void SpiritRadioSetPACwc(PALoadCapacitor xCLoad)
01820 {
01821   uint8_t tempRegValue;
01822   
01823   /* Check the parameters */
01824   s_assert_param(IS_PA_LOAD_CAP(xCLoad));
01825   
01826   /* Reads the PA_POWER_0 register */
01827   SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01828   
01829   /* Mask the CWC[1:0] field and write the new value */
01830   tempRegValue &= 0x3F;
01831   tempRegValue |= xCLoad;
01832   
01833   /* Configures the PA_POWER_0 register */
01834   g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01835   
01836 }
01837 
01838 
01839 /**
01840 * @brief  Returns the output stage additional load capacitor bank.
01841 * @param  None.
01842 * @retval PALoadCapacitor Output stage additional load capacitor bank.
01843 *         This parameter can be:
01844 *         @arg LOAD_0_PF    No additional PA load capacitor
01845 *         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
01846 *         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
01847 *         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
01848 */
01849 PALoadCapacitor SpiritRadioGetPACwc(void)
01850 {
01851   uint8_t tempRegValue;
01852   
01853   /* Reads the PA_POWER_0 register */
01854   g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01855   
01856   /* Mask the CWC[1:0] field and return the value*/
01857   return (PALoadCapacitor)(tempRegValue & 0xC0);
01858   
01859 }
01860 
01861 
01862 /**
01863 * @brief  Sets a specific PA_LEVEL_MAX_INDEX.
01864 * @param  cIndex PA_LEVEL_MAX_INDEX to set. This parameter shall be in the range [0:7].
01865 * @retval None
01866 */
01867 void SpiritRadioSetPALevelMaxIndex(uint8_t cIndex)
01868 {
01869   uint8_t tempRegValue;
01870   
01871   /* Check the parameters */
01872   s_assert_param(IS_PA_MAX_INDEX(cIndex));
01873   
01874   /* Reads the PA_POWER_0 register */
01875   SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01876   
01877   /* Mask the PA_LEVEL_MAX_INDEX[1:0] field and write the new value */
01878   tempRegValue &= 0xF8;
01879   tempRegValue |= cIndex;
01880   
01881   /* Configures the PA_POWER_0 register */
01882   g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01883   
01884 }
01885 
01886 
01887 /**
01888 * @brief  Returns the actual PA_LEVEL_MAX_INDEX.
01889 * @param  None.
01890 * @retval uint8_t Actual PA_LEVEL_MAX_INDEX. This parameter will be in the range [0:7].
01891 */
01892 uint8_t SpiritRadioGetPALevelMaxIndex(void)
01893 {
01894   uint8_t tempRegValue;
01895   
01896   /* Reads the PA_POWER_0 register */
01897   g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01898   
01899   /* Mask the PA_LEVEL_MAX_INDEX[1:0] field and return the value */
01900   return (tempRegValue & 0x07);
01901   
01902 }
01903 
01904 
01905 /**
01906 * @brief  Sets a specific PA_RAMP_STEP_WIDTH.
01907 * @param  cWidth step width expressed in terms of bit period units Tb/8.
01908 *         This parameter shall be in the range [1:4].
01909 * @retval None.
01910 */
01911 void SpiritRadioSetPAStepWidth(uint8_t cWidth)
01912 {
01913   uint8_t tempRegValue;
01914   
01915   /* Check the parameters */
01916   s_assert_param(IS_PA_STEP_WIDTH(cWidth));
01917   
01918   /* Reads the PA_POWER_0 register */
01919   SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01920   
01921   /* Mask the PA_RAMP_STEP_WIDTH[1:0] field and write the new value */
01922   tempRegValue &= 0xE7;
01923   tempRegValue |= (cWidth-1)<<3;
01924   
01925   /* Configures the PA_POWER_0 register */
01926   g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01927   
01928 }
01929 
01930 
01931 /**
01932 * @brief  Returns the actual PA_RAMP_STEP_WIDTH.
01933 * @param  None.
01934 * @retval uint8_t Step width value expressed in terms of bit period units Tb/8.
01935 *         This parameter will be in the range [1:4].
01936 */
01937 uint8_t SpiritRadioGetPAStepWidth(void)
01938 {
01939   uint8_t tempRegValue;
01940   
01941   /* Reads the PA_POWER_0 register */
01942   g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01943   
01944   /* Mask the PA_RAMP_STEP_WIDTH[1:0] field and return the value */
01945   tempRegValue &= 0x18;
01946   return  ((tempRegValue>>3)+1);
01947   
01948 }
01949 
01950 
01951 /**
01952 * @brief  Enables or Disables the Power Ramping.
01953 * @param  xNewState new state for power ramping.
01954 *         This parameter can be: S_ENABLE or S_DISABLE.
01955 * @retval None.
01956 */
01957 void SpiritRadioPARamping(SpiritFunctionalState xNewState)
01958 {
01959   uint8_t tempRegValue = 0x00;
01960   
01961   /* Check the parameters */
01962   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
01963   
01964   /* Reads the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
01965   SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01966   if(xNewState == S_ENABLE)
01967   {
01968     tempRegValue |= PA_POWER0_PA_RAMP_MASK;
01969   }
01970   else
01971   {
01972     tempRegValue &= (~PA_POWER0_PA_RAMP_MASK);
01973   }
01974   
01975   /* Sets the PA_POWER_0 register */
01976   g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01977   
01978 }
01979 
01980 /**
01981 * @brief  Returns the Power Ramping enable bit.
01982 * @param  xNewState new state for power ramping.
01983 *         This parameter can be: S_ENABLE or S_DISABLE.
01984 * @retval None.
01985 */
01986 SpiritFunctionalState SpiritRadioGetPARamping(void)
01987 {
01988   uint8_t tempRegValue;
01989   
01990   /* Reads the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
01991   g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
01992   
01993   /* Mask and return data */
01994   return (SpiritFunctionalState)((tempRegValue>>5) & 0x01);
01995   
01996 }
01997 
01998 
01999 /**
02000 * @brief  Enables or Disables the AFC.
02001 * @param  xNewState new state for AFC.
02002 *         This parameter can be: S_ENABLE or S_DISABLE.
02003 * @retval None.
02004 */
02005 void SpiritRadioAFC(SpiritFunctionalState xNewState)
02006 {
02007   uint8_t tempRegValue = 0x00;
02008   
02009   /* Check the parameters */
02010   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02011   
02012   /* Reads the AFC_2 register and configure the AFC Enabled field */
02013   SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02014   if(xNewState == S_ENABLE)
02015   {
02016     tempRegValue |= AFC2_AFC_MASK;
02017   }
02018   else
02019   {
02020     tempRegValue &= (~AFC2_AFC_MASK);
02021   }
02022   
02023   /* Sets the AFC_2 register */
02024   g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
02025   
02026 }
02027 
02028 
02029 /**
02030 * @brief  Enables or Disables the AFC freeze on sync word detection.
02031 * @param  xNewState new state for AFC freeze on sync word detection.
02032 *         This parameter can be: S_ENABLE or S_DISABLE.
02033 * @retval None.
02034 */
02035 void SpiritRadioAFCFreezeOnSync(SpiritFunctionalState xNewState)
02036 {
02037   uint8_t tempRegValue = 0x00;
02038   
02039   /* Check the parameters */
02040   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02041   
02042   /* Reads the AFC_2 register and configure the AFC Freeze on Sync field */
02043   SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02044   if(xNewState == S_ENABLE)
02045   {
02046     tempRegValue |= AFC2_AFC_FREEZE_ON_SYNC_MASK;
02047   }
02048   else
02049   {
02050     tempRegValue &= (~AFC2_AFC_FREEZE_ON_SYNC_MASK);
02051   }
02052   
02053   /* Sets the AFC_2 register */
02054   g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
02055   
02056 }
02057 
02058 
02059 /**
02060 * @brief  Sets the AFC working mode.
02061 * @param  xMode the AFC mode. This parameter can be one of the values defined in @ref AFCMode :
02062 *         @arg AFC_SLICER_CORRECTION     AFC loop closed on slicer
02063 *         @arg AFC_2ND_IF_CORRECTION     AFC loop closed on 2nd conversion stage
02064 * @retval None.
02065 */
02066 void SpiritRadioSetAFCMode(AFCMode xMode)
02067 {
02068   uint8_t tempRegValue = 0x00;
02069   
02070   /* Check the parameters */
02071   s_assert_param(IS_AFC_MODE(xMode));
02072   
02073   /* Reads the AFC_2 register and configure the AFC Mode field */
02074   SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02075   if(xMode == AFC_2ND_IF_CORRECTION )
02076   {
02077     tempRegValue |= AFC_2ND_IF_CORRECTION ;
02078   }
02079   else
02080   {
02081     tempRegValue &= (~AFC_2ND_IF_CORRECTION );
02082   }
02083   
02084   /* Sets the AFC_2 register */
02085   g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
02086   
02087 }
02088 
02089 
02090 /**
02091 * @brief  Returns the AFC working mode.
02092 * @param  None.
02093 * @retval AFCMode Settled AFC mode. This parameter will be one of the values defined in @ref AFCMode :
02094 *         @arg AFC_SLICER_CORRECTION     AFC loop closed on slicer
02095 *         @arg AFC_2ND_IF_CORRECTION     AFC loop closed on 2nd conversion stage
02096 */
02097 AFCMode SpiritRadioGetAFCMode(void)
02098 {
02099   uint8_t tempRegValue;
02100   
02101   /* Reads the AFC_2 register */
02102   g_xStatus = SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02103   
02104   /* Mask the AFC Mode field and returns the value */
02105   return (AFCMode)(tempRegValue & 0x20);
02106   
02107 }
02108 
02109 
02110 /**
02111 * @brief  Sets the AFC peak detector leakage.
02112 * @param  cLeakage the peak detector leakage. This parameter shall be in the range:
02113 *         [0:31].
02114 * @retval None.
02115 */
02116 void SpiritRadioSetAFCPDLeakage(uint8_t cLeakage)
02117 {
02118   uint8_t tempRegValue = 0x00;
02119   
02120   /* Check the parameters */
02121   s_assert_param(IS_AFC_PD_LEAKAGE(cLeakage));
02122   
02123   /* Reads the AFC_2 register and configure the AFC PD leakage field */
02124   SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02125   tempRegValue &= 0xE0;
02126   tempRegValue |= cLeakage;
02127   
02128   /* Sets the AFC_2 register */
02129   g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
02130   
02131 }
02132 
02133 
02134 /**
02135 * @brief  Returns the AFC peak detector leakage.
02136 * @param  None.
02137 * @retval uint8_t Peak detector leakage value. This parameter will be in the range:
02138 *         [0:31].
02139 */
02140 uint8_t SpiritRadioGetAFCPDLeakage(void)
02141 {
02142   uint8_t tempRegValue;
02143   
02144   /* Reads the AFC_2 register */
02145   g_xStatus = SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
02146   
02147   /* Mask the AFC PD leakage field and return the value */
02148   return (tempRegValue & 0x1F);
02149   
02150 }
02151 
02152 
02153 /**
02154 * @brief  Sets the length of the AFC fast period expressed as number of samples.
02155 * @param  cLength length of the fast period in number of samples.
02156 * @retval None.
02157 */
02158 void SpiritRadioSetAFCFastPeriod(uint8_t cLength)
02159 {
02160   /* Sets the AFC_1 register */
02161   g_xStatus = SpiritSpiWriteRegisters(AFC1_BASE, 1, &cLength);
02162   
02163 }
02164 
02165 
02166 /**
02167 * @brief  Returns the AFC fast period expressed as number of samples.
02168 * @param  None.
02169 * @retval uint8_t Length of the fast period in number of samples.
02170 */
02171 uint8_t SpiritRadioGetAFCFastPeriod(void)
02172 {
02173   uint8_t tempRegValue;
02174   
02175   /* Reads the AFC 1 register and return the value */
02176   g_xStatus = SpiritSpiReadRegisters(AFC1_BASE, 1, &tempRegValue);
02177   
02178   return tempRegValue;
02179   
02180 }
02181 
02182 
02183 /**
02184 * @brief  Sets the AFC loop gain in fast mode.
02185 * @param  cGain AFC loop gain in fast mode. This parameter shall be in the range:
02186 *         [0:15].
02187 * @retval None.
02188 */
02189 void SpiritRadioSetAFCFastGain(uint8_t cGain)
02190 {
02191   uint8_t tempRegValue = 0x00;
02192   
02193   /* Check the parameters */
02194   s_assert_param(IS_AFC_FAST_GAIN(cGain));
02195   
02196   /* Reads the AFC_0 register and configure the AFC Fast Gain field */
02197   SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
02198   tempRegValue &= 0x0F;
02199   tempRegValue |= cGain<<4;
02200   
02201   /* Sets the AFC_0 register */
02202   g_xStatus = SpiritSpiWriteRegisters(AFC0_BASE, 1, &tempRegValue);
02203   
02204 }
02205 
02206 
02207 /**
02208 * @brief  Returns the AFC loop gain in fast mode.
02209 * @param  None.
02210 * @retval uint8_t AFC loop gain in fast mode. This parameter will be in the range:
02211 *         [0:15].
02212 */
02213 uint8_t SpiritRadioGetAFCFastGain(void)
02214 {
02215   uint8_t tempRegValue;
02216   
02217   /* Reads the AFC_0 register, mask the AFC Fast Gain field and return the value  */
02218   g_xStatus = SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
02219   
02220   return ((tempRegValue & 0xF0)>>4);
02221   
02222 }
02223 
02224 
02225 /**
02226 * @brief  Sets the AFC loop gain in slow mode.
02227 * @param  cGain AFC loop gain in slow mode. This parameter shall be in the range:
02228 *         [0:15].
02229 * @retval None.
02230 */
02231 void SpiritRadioSetAFCSlowGain(uint8_t cGain)
02232 {
02233   uint8_t tempRegValue = 0x00;
02234   
02235   /* Check the parameters */
02236   s_assert_param(IS_AFC_SLOW_GAIN(cGain));
02237   
02238   /* Reads the AFC_0 register and configure the AFC Slow Gain field */
02239   SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
02240   tempRegValue &= 0xF0;
02241   tempRegValue |= cGain;
02242   
02243   /* Sets the AFC_0 register */
02244   g_xStatus = SpiritSpiWriteRegisters(AFC0_BASE, 1, &tempRegValue);
02245   
02246 }
02247 
02248 
02249 /**
02250 * @brief  Returns the AFC loop gain in slow mode.
02251 * @param  None.
02252 * @retval uint8_t AFC loop gain in slow mode. This parameter will be in the range:
02253 *         [0:15].
02254 */
02255 uint8_t SpiritRadioGetAFCSlowGain(void)
02256 {
02257   uint8_t tempRegValue;
02258   
02259   /* Reads the AFC_0 register, mask the AFC Slow Gain field and return the value */
02260   g_xStatus = SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
02261   
02262   return (tempRegValue & 0x0F);
02263   
02264 }
02265 
02266 
02267 /**
02268 * @brief  Returns the AFC correction from the corresponding register.
02269 * @param  None.
02270 * @retval int8_t AFC correction, read from the corresponding register.
02271 *         This parameter will be in the range [-128:127].
02272 */
02273 int8_t SpiritRadioGetAFCCorrectionReg(void)
02274 {
02275   uint8_t tempRegValue;
02276   
02277   /* Reads the AFC_CORR register, cast the read value as signed char and return it */
02278   g_xStatus = SpiritSpiReadRegisters(AFC_CORR_BASE, 1, &tempRegValue);
02279   
02280   return (int8_t)tempRegValue;
02281   
02282 }
02283 
02284 
02285 /**
02286 * @brief  Returns the AFC correction expressed in Hz.
02287 * @param  None.
02288 * @retval int32_t AFC correction expressed in Hz
02289 *         according to the following formula:<ul>
02290 *         <li> Fafc[Hz]= (Fdig/(12*2^10))*AFC_CORR  where </li>
02291 *         <li> AFC_CORR is the value read in the AFC_CORR register </li> </ul>
02292 */
02293 int32_t SpiritRadioGetAFCCorrectionHz(void)
02294 {
02295   int8_t correction;
02296   uint32_t xtal = s_lXtalFrequency;
02297   
02298   /* Reads the AFC correction register */
02299   correction = SpiritRadioGetAFCCorrectionReg();
02300   
02301   if(xtal>DOUBLE_XTAL_THR)
02302   {
02303     xtal /= 2;
02304   }
02305   
02306   /* Calculates and return the Frequency Correction */
02307   return (int32_t)(xtal/(12*pow(2,10))*correction);
02308   
02309 }
02310 
02311 
02312 /**
02313 * @brief  Enables or Disables the AGC.
02314 * @param  xNewState new state for AGC.
02315 *         This parameter can be: S_ENABLE or S_DISABLE
02316 * @retval None.
02317 */
02318 void SpiritRadioAGC(SpiritFunctionalState xNewState)
02319 {
02320   uint8_t tempRegValue = 0x00;
02321   
02322   /* Check the parameters */
02323   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02324   
02325   /* Reads the AGCCTRL_0 register and configure the AGC Enabled field */
02326   SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02327   if(xNewState == S_ENABLE)
02328   {
02329     tempRegValue |= AGCCTRL0_AGC_MASK;
02330   }
02331   else
02332   {
02333     tempRegValue &= (~AGCCTRL0_AGC_MASK);
02334   }
02335   
02336   /* Sets the AGCCTRL_0 register */
02337   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02338   
02339 }
02340 
02341 
02342 /**
02343 * @brief  Sets the AGC working mode.
02344 * @param  xMode the AGC mode. This parameter can be one of the values defined in @ref AGCMode :
02345 *         @arg AGC_LINEAR_MODE     AGC works in linear mode
02346 *         @arg AGC_BINARY_MODE     AGC works in binary mode
02347 * @retval None.
02348 */
02349 void SpiritRadioSetAGCMode(AGCMode xMode)
02350 {
02351   uint8_t tempRegValue = 0x00;
02352   
02353   /* Check the parameters */
02354   s_assert_param(IS_AGC_MODE(xMode));
02355   
02356   /* Reads the AGCCTRL_0 register and configure the AGC Mode field */
02357   SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02358   if(xMode == AGC_BINARY_MODE )
02359   {
02360     tempRegValue |= AGC_BINARY_MODE ;
02361   }
02362   else
02363   {
02364     tempRegValue &= (~AGC_BINARY_MODE );
02365   }
02366   
02367   /* Sets the AGCCTRL_0 register */
02368   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02369   
02370 }
02371 
02372 
02373 /**
02374 * @brief  Returns the AGC working mode.
02375 * @param  None.
02376 * @retval AGCMode Settled AGC mode.  This parameter can be one of the values defined in @ref AGCMode :
02377 *         @arg AGC_LINEAR_MODE     AGC works in linear mode
02378 *         @arg AGC_BINARY_MODE     AGC works in binary mode
02379 */
02380 AGCMode SpiritRadioGetAGCMode(void)
02381 {
02382   uint8_t tempRegValue;
02383   
02384   /* Reads the AGCCTRL_0 register, mask the AGC Mode field and return the value */
02385   g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02386   
02387   return  (AGCMode)(tempRegValue & 0x40);
02388   
02389 }
02390 
02391 
02392 /**
02393 * @brief  Enables or Disables the AGC freeze on steady state.
02394 * @param  xNewState new state for AGC freeze on steady state.
02395 *         This parameter can be: S_ENABLE or S_DISABLE.
02396 * @retval None.
02397 */
02398 void SpiritRadioAGCFreezeOnSteady(SpiritFunctionalState xNewState)
02399 {
02400   uint8_t tempRegValue = 0x00;
02401   
02402   /* Check the parameters */
02403   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02404   
02405   /* Reads the AGCCTRL_2 register and configure the AGC Freeze On Steady field */
02406   SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02407   if(xNewState == S_ENABLE)
02408   {
02409     tempRegValue |= AGCCTRL2_FREEZE_ON_STEADY_MASK;
02410   }
02411   else
02412   {
02413     tempRegValue &= (~AGCCTRL2_FREEZE_ON_STEADY_MASK);
02414   }
02415   
02416   /* Sets the AGCCTRL_2 register */
02417   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02418   
02419 }
02420 
02421 
02422 /**
02423 * @brief  Enable or Disable the AGC freeze on sync detection.
02424 * @param  xNewState new state for AGC freeze on sync detection.
02425 *         This parameter can be: S_ENABLE or S_DISABLE.
02426 * @retval None.
02427 */
02428 void SpiritRadioAGCFreezeOnSync(SpiritFunctionalState xNewState)
02429 {
02430   uint8_t tempRegValue = 0x00;
02431   
02432   /* Check the parameters */
02433   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02434   
02435   /* Reads the AGCCTRL_2 register and configure the AGC Freeze On Sync field */
02436   SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02437   if(xNewState == S_ENABLE)
02438   {
02439     tempRegValue |= AGCCTRL2_FREEZE_ON_SYNC_MASK;
02440   }
02441   else
02442   {
02443     tempRegValue &= (~AGCCTRL2_FREEZE_ON_SYNC_MASK);
02444   }
02445   
02446   /* Sets the AGCCTRL_2 register */
02447   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02448   
02449 }
02450 
02451 
02452 /**
02453 * @brief  Enable or Disable the AGC to start with max attenuation.
02454 * @param  xNewState new state for AGC start with max attenuation mode.
02455 *         This parameter can be: S_ENABLE or S_DISABLE.
02456 * @retval None.
02457 */
02458 void SpiritRadioAGCStartMaxAttenuation(SpiritFunctionalState xNewState)
02459 {
02460   uint8_t tempRegValue = 0x00;
02461   
02462   /* Check the parameters */
02463   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02464   
02465   /* Reads the AGCCTRL_2 register and configure the AGC Start Max Attenuation field */
02466   SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02467   if(xNewState == S_ENABLE)
02468   {
02469     tempRegValue |= AGCCTRL2_START_MAX_ATTENUATION_MASK;
02470   }
02471   else
02472   {
02473     tempRegValue &= (~AGCCTRL2_START_MAX_ATTENUATION_MASK);
02474   }
02475   
02476   /* Sets the AGCCTRL_2 register */
02477   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02478   
02479 }
02480 
02481 
02482 /**
02483 * @brief  Sets the AGC measure time.
02484 * @param  nTime AGC measure time expressed in us. This parameter shall be in the range [0, 393216/F_Xo].
02485 * @retval None.
02486 */
02487 void SpiritRadioSetAGCMeasureTimeUs(uint16_t nTime)
02488 {
02489   uint8_t tempRegValue, measure;
02490   
02491   /* Check the parameter */
02492   s_assert_param(IS_AGC_MEASURE_TIME_US(nTime,s_lXtalFrequency));
02493   
02494   /* Reads the AGCCTRL_2 register */
02495   SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02496   
02497   /* Calculates the measure time value to write in the register */
02498   measure = (uint8_t)lroundf(log2((float)nTime/1e6 * s_lXtalFrequency/12));
02499   (measure>15) ? (measure=15):(measure);
02500   
02501   /* Mask the MEAS_TIME field and write the new value */
02502   tempRegValue &= 0xF0;
02503   tempRegValue |= measure;
02504   
02505   /* Sets the AGCCTRL_2 register */
02506   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02507   
02508 }
02509 
02510 
02511 /**
02512 * @brief  Returns the AGC measure time.
02513 * @param  None.
02514 * @retval uint16_t AGC measure time expressed in us. This parameter will be in the range [0, 393216/F_Xo].
02515 */
02516 uint16_t SpiritRadioGetAGCMeasureTimeUs(void)
02517 {
02518   uint8_t measure;
02519   
02520   /* Reads the AGCCTRL_2 register */
02521   g_xStatus = SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &measure);
02522   
02523   /* Mask the MEAS_TIME field */
02524   measure &= 0x0F;
02525   
02526   /* Calculates the measure time value to write in the register */
02527   return (uint16_t)((12.0/s_lXtalFrequency)*(float)pow(2,measure)*1e6);
02528   
02529 }
02530 
02531 
02532 /**
02533 * @brief  Sets the AGC measure time.
02534 * @param  cTime AGC measure time to write in the MEAS_TIME field of AGCCTRL_2 register.
02535 *         This parameter shall be in the range [0:15].
02536 * @retval None.
02537 */
02538 void SpiritRadioSetAGCMeasureTime(uint8_t cTime)
02539 {
02540   uint8_t tempRegValue;
02541   
02542   /* Check the parameter */
02543   s_assert_param(IS_AGC_MEASURE_TIME(cTime));
02544   
02545   /* Reads the AGCCTRL_2 register */
02546   SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02547   
02548   /* Mask the MEAS_TIME field and write the new value */
02549   tempRegValue &= 0xF0;
02550   tempRegValue |= cTime;
02551   
02552   /* Sets the AGCCTRL_2 register */
02553   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02554   
02555 }
02556 
02557 
02558 /**
02559 * @brief  Returns the AGC measure time.
02560 * @param  None.
02561 * @retval uint8_t AGC measure time read from the MEAS_TIME field of AGCCTRL_2 register.
02562 *         This parameter will be in the range [0:15].
02563 */
02564 uint8_t SpiritRadioGetAGCMeasureTime(void)
02565 {
02566   uint8_t tempRegValue;
02567   
02568   /* Reads the AGCCTRL_2 register, mask the MEAS_TIME field and return the value  */
02569   g_xStatus = SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
02570   
02571   return (tempRegValue & 0x0F);
02572   
02573 }
02574 
02575 
02576 /**
02577 * @brief  Sets the AGC hold time.
02578 * @param  cTime AGC hold time expressed in us. This parameter shall be in the range[0, 756/F_Xo].
02579 * @retval None.
02580 */
02581 void SpiritRadioSetAGCHoldTimeUs(uint8_t cTime)
02582 {
02583   uint8_t tempRegValue, hold;
02584   
02585   /* Check the parameter */
02586   s_assert_param(IS_AGC_HOLD_TIME_US(cTime,s_lXtalFrequency));
02587   
02588   /* Reads the AGCCTRL_0 register */
02589   SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02590   
02591   /* Calculates the hold time value to write in the register */
02592   hold = (uint8_t)lroundf(((float)cTime/1e6 * s_lXtalFrequency)/12);
02593   (hold>63) ? (hold=63):(hold);
02594   
02595   /* Mask the HOLD_TIME field and write the new value */
02596   tempRegValue &= 0xC0;
02597   tempRegValue |= hold;
02598   
02599   /* Sets the AGCCTRL_0 register */
02600   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02601   
02602 }
02603 
02604 
02605 /**
02606 * @brief  Returns the AGC hold time.
02607 * @param  None.
02608 * @retval uint8_t AGC hold time expressed in us. This parameter will be in the range:
02609 *         [0, 756/F_Xo].
02610 */
02611 uint8_t SpiritRadioGetAGCHoldTimeUs(void)
02612 {
02613   uint8_t tempRegValue;
02614   
02615   /* Reads the AGCCTRL_0 register */
02616   g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02617   
02618   /* Mask the HOLD_TIME field */
02619   tempRegValue &= 0x3F;
02620   
02621   /* Calculates the hold time value and return it */
02622   return (uint8_t)lroundf ((12.0/s_lXtalFrequency)*(tempRegValue*1e6));
02623   
02624 }
02625 
02626 
02627 /**
02628 * @brief  Sets the AGC hold time.
02629 * @param  cTime AGC hold time to write in the HOLD_TIME field of AGCCTRL_0 register.
02630 *         This parameter shall be in the range [0:63].
02631 * @retval None.
02632 */
02633 void SpiritRadioSetAGCHoldTime(uint8_t cTime)
02634 {
02635   uint8_t tempRegValue;
02636   
02637   /* Check the parameter */
02638   s_assert_param(IS_AGC_HOLD_TIME(cTime));
02639   
02640   /* Reads the AGCCTRL_0 register */
02641   SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02642   
02643   /* Mask the HOLD_TIME field and write the new value */
02644   tempRegValue &= 0xC0;
02645   tempRegValue |= cTime;
02646   
02647   /* Sets the AGCCTRL_0 register */
02648   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02649   
02650 }
02651 
02652 
02653 /**
02654 * @brief  Returns the AGC hold time.
02655 * @param  None.
02656 * @retval uint8_t AGC hold time read from the HOLD_TIME field of AGCCTRL_0 register.
02657 *         This parameter will be in the range [0:63].
02658 */
02659 uint8_t SpiritRadioGetAGCHoldTime(void)
02660 {
02661   uint8_t tempRegValue;
02662   
02663   /* Reads the AGCCTRL_0 register, mask the MEAS_TIME field and return the value  */
02664   g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
02665   
02666   return (tempRegValue & 0x3F);
02667   
02668 }
02669 
02670 
02671 /**
02672 * @brief  Sets the AGC high threshold.
02673 * @param  cHighThreshold AGC high threshold to write in the THRESHOLD_HIGH field of AGCCTRL_1 register.
02674 *         This parameter shall be in the range [0:15].
02675 * @retval None.
02676 */
02677 void SpiritRadioSetAGCHighThreshold(uint8_t cHighThreshold)
02678 {
02679   uint8_t tempRegValue;
02680   
02681   /* Check the parameter */
02682   s_assert_param(IS_AGC_THRESHOLD(cHighThreshold));
02683   
02684   /* Reads the AGCCTRL_1 register */
02685   SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02686   
02687   /* Mask the THRESHOLD_HIGH field and write the new value */
02688   tempRegValue &= 0x0F;
02689   tempRegValue |= cHighThreshold<<4;
02690   
02691   /* Sets the AGCCTRL_1 register */
02692   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02693   
02694 }
02695 
02696 
02697 /**
02698 * @brief  Returns the AGC high threshold.
02699 * @param  None.
02700 * @retval uint8_t AGC high threshold read from the THRESHOLD_HIGH field of AGCCTRL_1 register.
02701 *         This parameter will be in the range [0:15].
02702 */
02703 uint8_t SpiritRadioGetAGCHighThreshold(void)
02704 {
02705   uint8_t tempRegValue;
02706   
02707   /* Reads the AGCCTRL_1 register, mask the THRESHOLD_HIGH field and return the value */
02708   g_xStatus = SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02709   
02710   return ((tempRegValue & 0xF0)>>4);
02711   
02712 }
02713 
02714 
02715 /**
02716 * @brief  Sets the AGC low threshold.
02717 * @param  cLowThreshold AGC low threshold to write in the THRESHOLD_LOW field of AGCCTRL_1 register.
02718 *         This parameter shall be in the range [0:15].
02719 * @retval None.
02720 */
02721 void SpiritRadioSetAGCLowThreshold(uint8_t cLowThreshold)
02722 {
02723   uint8_t tempRegValue;
02724   
02725   /* Check the parameter */
02726   s_assert_param(IS_AGC_THRESHOLD(cLowThreshold));
02727   
02728   /* Reads the AGCCTRL_1 register */
02729   SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02730   
02731   /* Mask the THRESHOLD_LOW field and write the new value */
02732   tempRegValue &= 0xF0;
02733   tempRegValue |= cLowThreshold;
02734   
02735   /* Sets the AGCCTRL_1 register */
02736   g_xStatus = SpiritSpiWriteRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02737   
02738 }
02739 
02740 
02741 /**
02742 * @brief  Returns the AGC low threshold.
02743 * @param  None.
02744 * @retval uint8_t AGC low threshold read from the THRESHOLD_LOW field of AGCCTRL_1 register.
02745 *         This parameter will be in the range [0:15].
02746 */
02747 uint8_t SpiritRadioGetAGCLowThreshold(void)
02748 {
02749   uint8_t tempRegValue;
02750   
02751   /* Reads the AGCCTRL_1 register, mask the THRESHOLD_LOW field and return the value  */
02752   g_xStatus = SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
02753   
02754   return (tempRegValue & 0x0F);
02755   
02756 }
02757 
02758 
02759 /**
02760 * @brief  Sets the clock recovery algorithm.
02761 * @param  xMode the Clock Recovery mode. This parameter can be one of the values defined in @ref ClkRecMode :
02762 *         @arg CLK_REC_PLL     PLL alogrithm for clock recovery
02763 *         @arg CLK_REC_DLL     DLL alogrithm for clock recovery
02764 * @retval None.
02765 */
02766 void SpiritRadioSetClkRecMode(ClkRecMode xMode)
02767 {
02768   uint8_t tempRegValue;
02769   
02770   /* Check the parameter */
02771   s_assert_param(IS_CLK_REC_MODE(xMode));
02772   
02773   /* Reads the FDEV_0 register */
02774   SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
02775   
02776   /* Mask the CLOCK_REC_ALGO_SEL field and write the new value */
02777   tempRegValue &= 0xF7;
02778   tempRegValue |= (uint8_t)xMode;
02779   
02780   /* Sets the FDEV_0 register */
02781   g_xStatus = SpiritSpiWriteRegisters(FDEV0_BASE, 1, &tempRegValue);
02782   
02783 }
02784 
02785 
02786 /**
02787 * @brief  Returns the Clock Recovery working mode.
02788 * @param  None.
02789 * @retval ClkRecMode Clock Recovery mode. This parameter can be one of the values defined in @ref ClkRecMode :
02790 *         @arg CLK_REC_PLL     PLL alogrithm for clock recovery
02791 *         @arg CLK_REC_DLL     DLL alogrithm for clock recovery
02792 */
02793 ClkRecMode SpiritRadioGetClkRecMode(void)
02794 {
02795   uint8_t tempRegValue;
02796   
02797   /* Reads the FDEV_0 register, mask the CLOCK_REC_ALGO_SEL field and return the value */
02798   g_xStatus = SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
02799   
02800   return (ClkRecMode)(tempRegValue & 0x08);
02801   
02802 }
02803 
02804 
02805 /**
02806 * @brief  Sets the clock recovery proportional gain.
02807 * @param  cPGain the Clock Recovery proportional gain to write in the CLK_REC_P_GAIN field of CLOCKREC register.
02808 *         It represents is log2 value of the clock recovery proportional gain.
02809 *          This parameter shall be in the range [0:7].
02810 * @retval None.
02811 */
02812 void SpiritRadioSetClkRecPGain(uint8_t cPGain)
02813 {
02814   uint8_t tempRegValue;
02815   
02816   /* Check the parameter */
02817   s_assert_param(IS_CLK_REC_P_GAIN(cPGain));
02818   
02819   /* Reads the CLOCKREC register */
02820   SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02821   
02822   /* Mask the CLK_REC_P_GAIN field and write the new value */
02823   tempRegValue &= 0x1F;
02824   tempRegValue |= (cPGain<<5);
02825   
02826   /* Sets the CLOCKREC register */
02827   g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02828   
02829 }
02830 
02831 
02832 /**
02833 * @brief  Returns the log2 of the clock recovery proportional gain.
02834 * @param  None.
02835 * @retval uint8_t Clock Recovery proportional gain read from the CLK_REC_P_GAIN field of CLOCKREC register.
02836 *         This parameter will be in the range [0:7].
02837 */
02838 uint8_t SpiritRadioGetClkRecPGain(void)
02839 {
02840   uint8_t tempRegValue;
02841   
02842   /* Reads the CLOCKREC register, mask the CLK_REC_P_GAIN field and return the value  */
02843   g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02844   
02845   return ((tempRegValue & 0xEF)>>5);
02846   
02847 }
02848 
02849 
02850 /**
02851 * @brief  Sets the clock recovery integral gain.
02852 * @param  cIGain the Clock Recovery integral gain to write in the CLK_REC_I_GAIN field of CLOCKREC register.
02853 *         This parameter shall be in the range [0:15].
02854 * @retval None.
02855 */
02856 void SpiritRadioSetClkRecIGain(uint8_t cIGain)
02857 {
02858   uint8_t tempRegValue;
02859   
02860   /* Check the parameter */
02861   s_assert_param(IS_CLK_REC_I_GAIN(cIGain));
02862   
02863   /* Reads the CLOCKREC register */
02864   SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02865   
02866   /* Mask the CLK_REC_P_GAIN field and write the new value */
02867   tempRegValue &= 0xF0;
02868   tempRegValue |= cIGain;
02869   
02870   /* Sets the CLOCKREC register */
02871   g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02872   
02873 }
02874 
02875 
02876 /**
02877 * @brief  Returns the clock recovery integral gain.
02878 * @param  None.
02879 * @retval uint8_t Clock Recovery integral gain read from the
02880 *         CLK_REC_I_GAIN field of CLOCKREC register.
02881 *         This parameter will be in the range [0:15].
02882 */
02883 uint8_t SpiritRadioGetClkRecIGain(void)
02884 {
02885   uint8_t tempRegValue;
02886   
02887   /* Reads the CLOCKREC register, mask the CLK_REC_I_GAIN field and return the value */
02888   g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02889   
02890   return (tempRegValue & 0x0F);
02891   
02892 }
02893 
02894 
02895 /**
02896 * @brief  Sets the postfilter length for clock recovery algorithm.
02897 * @param  xLength the postfilter length in symbols. This parameter can be one of the values defined in @ref PstFltLength :
02898 *         @arg PSTFLT_LENGTH_8     Postfilter length is 8 symbols
02899 *         @arg PSTFLT_LENGTH_16    Postfilter length is 16 symbols
02900 * @retval None.
02901 */
02902 void SpiritRadioSetClkRecPstFltLength(PstFltLength xLength)
02903 {
02904   uint8_t tempRegValue;
02905   
02906   /* Check the parameter */
02907   s_assert_param(IS_PST_FLT_LENGTH(xLength));
02908   
02909   /* Reads the CLOCKREC register */
02910   SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02911   
02912   /* Mask the PSTFLT_LEN field and write the new value */
02913   tempRegValue &= 0xEF;
02914   tempRegValue |= (uint8_t)xLength;
02915   
02916   /* Sets the CLOCKREC register */
02917   g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02918   
02919 }
02920 
02921 
02922 /**
02923 * @brief  Returns the postfilter length for clock recovery algorithm.
02924 * @param  None.
02925 * @retval PstFltLength Postfilter length in symbols. This parameter can be one of the values defined in @ref PstFltLength :
02926 *         @arg PSTFLT_LENGTH_8     Postfilter length is 8 symbols
02927 *         @arg PSTFLT_LENGTH_16    Postfilter length is 16 symbols
02928 */
02929 PstFltLength SpiritRadioGetClkRecPstFltLength(void)
02930 {
02931   uint8_t tempRegValue;
02932   
02933   /* Reads the CLOCKREC register, mask the PSTFLT_LEN field and return the value */
02934   g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
02935   
02936   return (PstFltLength)(tempRegValue & 0x10);
02937   
02938 }
02939 
02940 
02941 /**
02942 * @brief  Enables or Disables the received data blanking when the CS is under the threshold.
02943 * @param  xNewState new state of this mode.
02944 *         This parameter can be: S_ENABLE or S_DISABLE .
02945 * @retval None.
02946 */
02947 void SpiritRadioCsBlanking(SpiritFunctionalState xNewState)
02948 {
02949   uint8_t tempRegValue;
02950   
02951   /* Check the parameters */
02952   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02953   
02954   /* Reads the ANT_SELECT_CONF_BASE and mask the CS_BLANKING BIT field */
02955   SpiritSpiReadRegisters(ANT_SELECT_CONF_BASE, 1, &tempRegValue);
02956   
02957   if(xNewState == S_ENABLE)
02958   {
02959     tempRegValue |= ANT_SELECT_CS_BLANKING_MASK;
02960   }
02961   else
02962   {
02963     tempRegValue &= (~ANT_SELECT_CS_BLANKING_MASK);
02964   }
02965   
02966   /* Writes the new value in the ANT_SELECT_CONF register */
02967   g_xStatus = SpiritSpiWriteRegisters(ANT_SELECT_CONF_BASE, 1, &tempRegValue);
02968   
02969   
02970 }
02971 
02972 /**
02973 * @brief  Enables or Disables the persistent RX mode.
02974 * @param  xNewState new state of this mode.
02975 *         This parameter can be: S_ENABLE or S_DISABLE .
02976 * @retval None.
02977 */
02978 void SpiritRadioPersistenRx(SpiritFunctionalState xNewState)
02979 {
02980   uint8_t tempRegValue;
02981   
02982   /* Check the parameters */
02983   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
02984   
02985   /* Reads the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */
02986   SpiritSpiReadRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
02987   
02988   if(xNewState == S_ENABLE)
02989   {
02990     tempRegValue |= PROTOCOL0_PERS_RX_MASK;
02991   }
02992   else
02993   {
02994     tempRegValue &= (~PROTOCOL0_PERS_RX_MASK);
02995   }
02996   
02997   /* Writes the new value in the PROTOCOL0_BASE register */
02998   g_xStatus = SpiritSpiWriteRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
02999   
03000 }
03001 
03002 /**
03003 * @brief  Enables or Disables the synthesizer reference divider.
03004 * @param  xNewState new state for synthesizer reference divider.
03005 *         This parameter can be: S_ENABLE or S_DISABLE .
03006 * @retval None.
03007 */
03008 void SpiritRadioSetRefDiv(SpiritFunctionalState xNewState)
03009 {
03010   uint8_t tempRegValue;
03011   
03012   /* Check the parameters */
03013   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
03014   
03015   /* Reads the SYNTH_CONFIG1_BASE and mask the REFDIV bit field */
03016   SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
03017   
03018   if(xNewState == S_ENABLE)
03019   {
03020     tempRegValue |= 0x80;
03021   }
03022   else
03023   {
03024     tempRegValue &= 0x7F;
03025   }
03026   
03027   /* Writes the new value in the SYNTH_CONFIG1_BASE register */
03028   g_xStatus = SpiritSpiWriteRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
03029   
03030 }
03031 
03032 /**
03033 * @brief  Get the the synthesizer reference divider state.
03034 * @param  void.
03035 * @retval None.
03036 */
03037 SpiritFunctionalState SpiritRadioGetRefDiv(void)
03038 {
03039   uint8_t tempRegValue;
03040   
03041   g_xStatus = SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
03042   
03043   if(((tempRegValue>>7)&0x1))
03044   {
03045     return S_ENABLE;
03046   }
03047   else
03048   {
03049     return S_DISABLE;
03050   }
03051   
03052 }
03053 
03054 /**
03055 * @brief  Enables or Disables the synthesizer reference divider.
03056 * @param  xNewState new state for synthesizer reference divider.
03057 *         This parameter can be: S_ENABLE or S_DISABLE .
03058 * @retval None.
03059 */
03060 void SpiritRadioSetDigDiv(SpiritFunctionalState xNewState)
03061 {
03062   uint8_t tempRegValue;
03063   
03064   /* Check the parameters */
03065   s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
03066   
03067   /* Reads the XO_RCO_TEST_BASE and mask the PD_CLKDIV bit field */
03068   SpiritSpiReadRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
03069   
03070   if(xNewState == S_ENABLE)
03071   {
03072     tempRegValue &= 0xf7;
03073   }
03074   else
03075   {
03076     
03077     tempRegValue |= 0x08;
03078   }
03079   
03080   /* Writes the new value in the XO_RCO_TEST_BASE register */
03081   g_xStatus = SpiritSpiWriteRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
03082   
03083 }
03084 
03085 /**
03086 * @brief  Get the the synthesizer reference divider state.
03087 * @param  void.
03088 * @retval None.
03089 */
03090 SpiritFunctionalState SpiritRadioGetDigDiv(void)
03091 {
03092   uint8_t tempRegValue;
03093   
03094   g_xStatus = SpiritSpiReadRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
03095   
03096   if(((tempRegValue>>3)&0x1))
03097   {
03098     return S_DISABLE;
03099   }
03100   else
03101   {
03102     return S_ENABLE;
03103   }
03104   
03105 }
03106 
03107 /**
03108 * @brief  Returns the XTAL frequency.
03109 * @param  void.
03110 * @retval uint32_t XTAL frequency.
03111 */
03112 uint32_t SpiritRadioGetXtalFrequency(void)
03113 {
03114   return s_lXtalFrequency; 
03115 }
03116 
03117 /**
03118 * @brief  Sets the XTAL frequency.
03119 * @param  uint32_t XTAL frequency.
03120 * @retval void.
03121 */
03122 void SpiritRadioSetXtalFrequency(uint32_t lXtalFrequency)
03123 {
03124   s_lXtalFrequency = lXtalFrequency; 
03125 }
03126 
03127 /**
03128 * @}
03129 */
03130 
03131 
03132 /**
03133 * @}
03134 */
03135 
03136 
03137 /**
03138 * @}
03139 */
03140 
03141 
03142 
03143 /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
03144