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