JunMo Hong / EV-COG-AD3029LZ

Fork of stm-spirit1-rf-driver by ST

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