JunMo Hong / EV-COG-AD3029LZ

Fork of stm-spirit1-rf-driver by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPIRIT_Management.c Source File

SPIRIT_Management.c

Go to the documentation of this file.
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>&copy; 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****/