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