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_Management.c
00001 /** 00002 ****************************************************************************** 00003 * @file SPIRIT_Management.c 00004 * @author VMA division - AMS 00005 * @version 3.2.2 00006 * @date 08-July-2015 00007 * @brief The management layer for SPIRIT1 library. 00008 * @details 00009 * 00010 * @attention 00011 * 00012 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00013 * 00014 * Redistribution and use in source and binary forms, with or without modification, 00015 * are permitted provided that the following conditions are met: 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00022 * may be used to endorse or promote products derived from this software 00023 * without specific prior written permission. 00024 * 00025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00028 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00029 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00030 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00031 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00033 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00034 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 ****************************************************************************** 00037 */ 00038 00039 /* Includes ------------------------------------------------------------------*/ 00040 #include "SPIRIT_Management.h" 00041 00042 /** 00043 * @addtogroup SPIRIT_Libraries 00044 * @{ 00045 */ 00046 00047 00048 /** 00049 * @defgroup SPIRIT_MANAGEMENT SPIRIT Management 00050 * @{ 00051 */ 00052 00053 00054 00055 //180619 HJM : init 재시작을 위한 카운팅 변수 00056 static int iSpiritManagementErrorCounting = 0; 00057 #define MAX_ERROR_COUNTING 3 00058 #define RETURN_ERROR_NUMBER 100 00059 00060 00061 /** 00062 * @brief BS value to write in the SYNT0 register according to the selected band 00063 */ 00064 static const uint8_t s_vectcBandRegValue[4]={SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32}; 00065 00066 #define COMMUNICATION_STATE_TX 0 00067 #define COMMUNICATION_STATE_RX 1 00068 #define COMMUNICATION_STATE_NONE 2 00069 00070 static uint32_t s_nDesiredFrequency; 00071 00072 static volatile uint8_t s_cCommunicationState = COMMUNICATION_STATE_NONE; 00073 00074 00075 /** 00076 * @brief Factor is: B/2 used in the formula for SYNTH word calculation 00077 */ 00078 static const uint8_t s_vectcBHalfFactor[4]={(HIGH_BAND_FACTOR/2), (MIDDLE_BAND_FACTOR/2), (LOW_BAND_FACTOR/2), (VERY_LOW_BAND_FACTOR/2)}; 00079 00080 00081 /** 00082 * @defgroup SPIRIT_MANAGEMENT_FUNCTIONS SPIRIT Management Functions 00083 * @{ 00084 */ 00085 00086 00087 /** 00088 * @defgroup WORKAROUND_FUNCTIONS SPIRIT Management Workaround Functions 00089 * @{ 00090 */ 00091 00092 /** 00093 * @brief Private SpiritRadioSetFrequencyBase function only used in SpiritManagementWaVcoCalibration. 00094 * @param lFBase the base carrier frequency expressed in Hz as unsigned word. 00095 * @retval None. 00096 */ 00097 int SpiritManagementSetFrequencyBase(uint32_t lFBase) 00098 { 00099 uint32_t synthWord, Fc; 00100 uint8_t band = 0, anaRadioRegArray[4], wcp; 00101 00102 int iRet = 0; 00103 00104 /* Check the parameter */ 00105 iRet = s_assert_param(IS_FREQUENCY_BAND(lFBase)); 00106 if (RETURN_ERROR_NUMBER == iRet) 00107 { 00108 return RETURN_ERROR_NUMBER; 00109 } 00110 00111 /* Search the operating band */ 00112 if(IS_FREQUENCY_BAND_HIGH(lFBase)) 00113 { 00114 band = HIGH_BAND ; 00115 } 00116 else if(IS_FREQUENCY_BAND_MIDDLE(lFBase)) 00117 { 00118 band = MIDDLE_BAND ; 00119 } 00120 else if(IS_FREQUENCY_BAND_LOW(lFBase)) 00121 { 00122 band = LOW_BAND ; 00123 } 00124 else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase)) 00125 { 00126 band = VERY_LOW_BAND ; 00127 } 00128 00129 int32_t FOffset = SpiritRadioGetFrequencyOffset(); 00130 uint32_t lChannelSpace = SpiritRadioGetChannelSpace(); 00131 uint8_t cChannelNum = SpiritRadioGetChannel(); 00132 00133 /* Calculates the channel center frequency */ 00134 Fc = lFBase + FOffset + lChannelSpace*cChannelNum; 00135 //180619 HJM : 여기까지는 spirit1 의 상태값을 그냥 한번만 spi 통신으로 읽어와 저장함. 00136 00137 00138 00139 00140 00141 00142 00143 /* Reads the reference divider */ 00144 uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1; 00145 00146 switch(band) 00147 { 00148 case VERY_LOW_BAND : 00149 if(Fc<161281250) 00150 { 00151 SpiritCalibrationSelectVco(VCO_L); 00152 } 00153 else 00154 { 00155 SpiritCalibrationSelectVco(VCO_H); 00156 } 00157 break; 00158 00159 case LOW_BAND : 00160 if(Fc<322562500) 00161 { 00162 SpiritCalibrationSelectVco(VCO_L); 00163 } 00164 else 00165 { 00166 SpiritCalibrationSelectVco(VCO_H); 00167 } 00168 break; 00169 00170 case MIDDLE_BAND : 00171 if(Fc<430083334) 00172 { 00173 SpiritCalibrationSelectVco(VCO_L); 00174 } 00175 else 00176 { 00177 SpiritCalibrationSelectVco(VCO_H); 00178 } 00179 break; 00180 00181 case HIGH_BAND : 00182 if(Fc<860166667) 00183 { 00184 SpiritCalibrationSelectVco(VCO_L); 00185 } 00186 else 00187 { 00188 SpiritCalibrationSelectVco(VCO_H); 00189 } 00190 } 00191 00192 /* Search the VCO charge pump word and set the corresponding register */ 00193 wcp = SpiritRadioSearchWCP(Fc); 00194 00195 synthWord = (uint32_t)(lFBase*(((double)(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band]))/SpiritRadioGetXtalFrequency())); 00196 00197 /* Build the array of registers values for the analog part */ 00198 anaRadioRegArray[0] = (uint8_t)(((synthWord>>21)&(0x0000001F))|(wcp<<5)); 00199 anaRadioRegArray[1] = (uint8_t)((synthWord>>13)&(0x000000FF)); 00200 anaRadioRegArray[2] = (uint8_t)((synthWord>>5)&(0x000000FF)); 00201 anaRadioRegArray[3] = (uint8_t)(((synthWord&0x0000001F)<<3)| s_vectcBandRegValue[band]); 00202 00203 /* Configures the needed Analog Radio registers */ 00204 g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, anaRadioRegArray); 00205 00206 return 0; 00207 } 00208 00209 uint8_t SpiritManagementWaVcoCalibration(void) 00210 { 00211 uint8_t s_cVcoWordRx; 00212 uint8_t s_cVcoWordTx; 00213 uint32_t nFreq; 00214 uint8_t cRestore = 0; 00215 uint8_t cStandby = 0; 00216 uint32_t xtal_frequency = SpiritRadioGetXtalFrequency(); 00217 00218 int iRet = 0; 00219 00220 /* Enable the reference divider if the XTAL is between 48 and 52 MHz */ 00221 if(xtal_frequency>DOUBLE_XTAL_THR) 00222 { 00223 if(!SpiritRadioGetRefDiv()) 00224 { 00225 cRestore = 1; 00226 nFreq = SpiritRadioGetFrequencyBase(); 00227 SpiritRadioSetRefDiv(S_ENABLE); 00228 //180621 HJM : 여기(아래) 수정함 00229 iRet = SpiritManagementSetFrequencyBase(nFreq); 00230 if (RETURN_ERROR_NUMBER == iRet) 00231 { 00232 return RETURN_ERROR_NUMBER; 00233 } 00234 } 00235 } 00236 nFreq = SpiritRadioGetFrequencyBase(); 00237 00238 /* Increase the VCO current */ 00239 uint8_t tmp = 0x19; SpiritSpiWriteRegisters(0xA1,1,&tmp); 00240 00241 SpiritCalibrationVco(S_ENABLE); 00242 00243 SpiritRefreshStatus(); 00244 printf("test 9-3 g_xStatus.MC_STATE : [0x%02X] \n", g_xStatus.MC_STATE); 00245 if(g_xStatus.MC_STATE == MC_STATE_STANDBY) 00246 { 00247 cStandby = 1; 00248 SpiritCmdStrobeReady(); 00249 printf("test 9-3 1 g_xStatus.MC_STATE : [0x%02X] \n", g_xStatus.MC_STATE); 00250 do 00251 { 00252 SpiritRefreshStatus(); 00253 printf("test 9-3 2 g_xStatus.MC_STATE : [0x%02X]\n", g_xStatus.MC_STATE); 00254 if(g_xStatus.MC_STATE == 0x13) 00255 { 00256 return 1; 00257 } 00258 00259 ++iSpiritManagementErrorCounting; 00260 if (iSpiritManagementErrorCounting >= MAX_ERROR_COUNTING) 00261 { 00262 iSpiritManagementErrorCounting = 0; 00263 return RETURN_ERROR_NUMBER; 00264 } 00265 00266 }while(g_xStatus.MC_STATE != MC_STATE_READY); 00267 } 00268 iSpiritManagementErrorCounting = 0; 00269 00270 00271 00272 00273 00274 SpiritCmdStrobeLockTx(); 00275 printf("test 9-4 g_xStatus.MC_STATE : [0x%02X] \n", g_xStatus.MC_STATE); 00276 do 00277 { 00278 SpiritRefreshStatus(); 00279 printf("test 9-4 1 g_xStatus.MC_STATE : [0x%02X] \n", g_xStatus.MC_STATE); 00280 if(g_xStatus.MC_STATE == 0x13) 00281 { 00282 return 1; 00283 } 00284 00285 ++iSpiritManagementErrorCounting; 00286 if (iSpiritManagementErrorCounting >= MAX_ERROR_COUNTING) 00287 { 00288 iSpiritManagementErrorCounting = 0; 00289 return RETURN_ERROR_NUMBER; 00290 } 00291 00292 }while(g_xStatus.MC_STATE != MC_STATE_LOCK); 00293 iSpiritManagementErrorCounting = 0; 00294 00295 00296 00297 00298 00299 s_cVcoWordTx = SpiritCalibrationGetVcoCalData(); 00300 00301 SpiritCmdStrobeReady(); 00302 printf("test 9-5 g_xStatus.MC_STATE : [0x%02X] \n", g_xStatus.MC_STATE); 00303 do{ 00304 SpiritRefreshStatus(); 00305 00306 ++iSpiritManagementErrorCounting; 00307 if (iSpiritManagementErrorCounting >= MAX_ERROR_COUNTING) 00308 { 00309 iSpiritManagementErrorCounting = 0; 00310 // reset_board(); 00311 return RETURN_ERROR_NUMBER; 00312 } 00313 00314 }while(g_xStatus.MC_STATE != MC_STATE_READY); 00315 iSpiritManagementErrorCounting = 0; 00316 00317 00318 SpiritCmdStrobeLockRx(); 00319 00320 do{ 00321 SpiritRefreshStatus(); 00322 if(g_xStatus.MC_STATE == 0x13) 00323 { 00324 return 1; 00325 } 00326 00327 ++iSpiritManagementErrorCounting; 00328 if (iSpiritManagementErrorCounting >= MAX_ERROR_COUNTING) 00329 { 00330 iSpiritManagementErrorCounting = 0; 00331 return RETURN_ERROR_NUMBER; 00332 } 00333 00334 }while(g_xStatus.MC_STATE != MC_STATE_LOCK); 00335 iSpiritManagementErrorCounting = 0; 00336 00337 s_cVcoWordRx = SpiritCalibrationGetVcoCalData(); 00338 00339 SpiritCmdStrobeReady(); 00340 00341 do 00342 { 00343 SpiritRefreshStatus(); 00344 if(g_xStatus.MC_STATE == 0x13) 00345 { 00346 return 1; 00347 } 00348 00349 ++iSpiritManagementErrorCounting; 00350 if (iSpiritManagementErrorCounting >= MAX_ERROR_COUNTING) 00351 { 00352 iSpiritManagementErrorCounting = 0; 00353 return RETURN_ERROR_NUMBER; 00354 } 00355 00356 }while(g_xStatus.MC_STATE != MC_STATE_READY); 00357 iSpiritManagementErrorCounting = 0; 00358 00359 00360 if(cStandby == 1) 00361 { 00362 SpiritCmdStrobeStandby(); 00363 } 00364 SpiritCalibrationVco(S_DISABLE); 00365 00366 /* Disable the reference divider if the XTAL is between 48 and 52 MHz */ 00367 if(cRestore) 00368 { 00369 SpiritRadioSetRefDiv(S_DISABLE); 00370 //180621 HJM : 여기(아래) 수정함 00371 iRet = SpiritManagementSetFrequencyBase(nFreq); 00372 if (RETURN_ERROR_NUMBER == iRet) 00373 { 00374 return RETURN_ERROR_NUMBER; 00375 } 00376 } 00377 00378 /* Restore the VCO current */ 00379 tmp = 0x11; SpiritSpiWriteRegisters(0xA1,1,&tmp); 00380 00381 SpiritCalibrationSetVcoCalDataTx(s_cVcoWordTx); 00382 SpiritCalibrationSetVcoCalDataRx(s_cVcoWordRx); 00383 00384 return 0; 00385 } 00386 00387 00388 void SpiritManagementWaCmdStrobeTx(void) 00389 { 00390 if(s_cCommunicationState != COMMUNICATION_STATE_TX) 00391 { 00392 //uint32_t xtal_frequency = SpiritRadioGetXtalFrequency(); 00393 00394 /* To achive the max output power */ 00395 if(s_nDesiredFrequency>=150000000 && s_nDesiredFrequency<=470000000) 00396 { 00397 /* Optimal setting for Tx mode only */ 00398 SpiritRadioSetPACwc(LOAD_3_6_PF ); 00399 } 00400 else 00401 { 00402 /* Optimal setting for Tx mode only */ 00403 SpiritRadioSetPACwc(LOAD_0_PF ); 00404 } 00405 00406 uint8_t tmp = 0x11; SpiritSpiWriteRegisters(0xa9, 1, &tmp); /* Enable VCO_L buffer */ 00407 tmp = 0x20; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */ 00408 00409 s_cCommunicationState = COMMUNICATION_STATE_TX; 00410 } 00411 } 00412 00413 00414 void SpiritManagementWaCmdStrobeRx(void) 00415 { 00416 if(s_cCommunicationState != COMMUNICATION_STATE_RX) 00417 { 00418 uint8_t tmp = 0x98; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */ 00419 SpiritRadioSetPACwc(LOAD_0_PF ); /* Set the correct CWC parameter */ 00420 00421 s_cCommunicationState = COMMUNICATION_STATE_RX; 00422 } 00423 } 00424 00425 void SpiritManagementWaTRxFcMem(uint32_t nDesiredFreq) 00426 { 00427 s_cCommunicationState = COMMUNICATION_STATE_NONE; 00428 s_nDesiredFrequency = nDesiredFreq; 00429 } 00430 00431 00432 void SpiritManagementWaExtraCurrent(void) 00433 { 00434 uint8_t tmp= 0xCA;SpiritSpiWriteRegisters(0xB2, 1, &tmp); 00435 tmp= 0x04;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 00436 /* just a read to loose some microsecs more */ 00437 SpiritSpiReadRegisters(0xA8, 1, &tmp); 00438 tmp= 0x00;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 00439 } 00440 00441 /** 00442 * @} 00443 */ 00444 00445 00446 00447 /** 00448 * @} 00449 */ 00450 00451 00452 /** 00453 * @} 00454 */ 00455 00456 /** 00457 * @} 00458 */ 00459 00460 00461 /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 13 2022 00:11:56 by
1.7.2
