Fork of my original MQTTGateway

Dependencies:   mbed-http

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 * @brief  BS value to write in the SYNT0 register according to the selected band
00055 */
00056 static const uint8_t s_vectcBandRegValue[4]={SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32};
00057 
00058 #define COMMUNICATION_STATE_TX          0
00059 #define COMMUNICATION_STATE_RX          1
00060 #define COMMUNICATION_STATE_NONE        2
00061 
00062 static uint32_t s_nDesiredFrequency;
00063 
00064 static volatile uint8_t s_cCommunicationState = COMMUNICATION_STATE_NONE;
00065 
00066 
00067 /**
00068 * @brief  Factor is: B/2 used in the formula for SYNTH word calculation
00069 */
00070 static const uint8_t s_vectcBHalfFactor[4]={(HIGH_BAND_FACTOR/2), (MIDDLE_BAND_FACTOR/2), (LOW_BAND_FACTOR/2), (VERY_LOW_BAND_FACTOR/2)};
00071 
00072 
00073 /**
00074 * @defgroup SPIRIT_MANAGEMENT_FUNCTIONS    SPIRIT Management Functions
00075 * @{
00076 */
00077 
00078 
00079 /**
00080 * @defgroup WORKAROUND_FUNCTIONS              SPIRIT Management Workaround Functions
00081 * @{
00082 */
00083 
00084 /**
00085 * @brief  Private SpiritRadioSetFrequencyBase function only used in SpiritManagementWaVcoCalibration.
00086 * @param  lFBase the base carrier frequency expressed in Hz as unsigned word.
00087 * @retval None.
00088 */
00089 void SpiritManagementSetFrequencyBase(uint32_t lFBase)
00090 {
00091   uint32_t synthWord, Fc;
00092   uint8_t band = 0, anaRadioRegArray[4], wcp;
00093   
00094   /* Check the parameter */
00095   s_assert_param(IS_FREQUENCY_BAND(lFBase));
00096   
00097   /* Search the operating band */
00098   if(IS_FREQUENCY_BAND_HIGH(lFBase))
00099   {
00100     band = HIGH_BAND ;
00101   }
00102   else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
00103   {
00104     band = MIDDLE_BAND ;
00105   }
00106   else if(IS_FREQUENCY_BAND_LOW(lFBase))
00107   {
00108     band = LOW_BAND ;
00109   }
00110   else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
00111   {
00112     band = VERY_LOW_BAND ;
00113   }
00114   
00115   int32_t FOffset  = SpiritRadioGetFrequencyOffset();
00116   uint32_t lChannelSpace  = SpiritRadioGetChannelSpace();
00117   uint8_t cChannelNum = SpiritRadioGetChannel();
00118   
00119   /* Calculates the channel center frequency */
00120   Fc = lFBase + FOffset + lChannelSpace*cChannelNum;
00121   
00122   /* Reads the reference divider */
00123   uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
00124   
00125   switch(band)
00126   {
00127   case VERY_LOW_BAND :
00128     if(Fc<161281250)
00129     {
00130       SpiritCalibrationSelectVco(VCO_L);
00131     }
00132     else
00133     {
00134       SpiritCalibrationSelectVco(VCO_H);
00135     }
00136     break;
00137     
00138   case LOW_BAND :
00139     if(Fc<322562500)
00140     {
00141       SpiritCalibrationSelectVco(VCO_L);
00142     }
00143     else
00144     {
00145       SpiritCalibrationSelectVco(VCO_H);
00146     }
00147     break;
00148     
00149   case MIDDLE_BAND :
00150     if(Fc<430083334)
00151     {
00152       SpiritCalibrationSelectVco(VCO_L);
00153     }
00154     else
00155     {
00156       SpiritCalibrationSelectVco(VCO_H);
00157     }
00158     break;
00159     
00160   case HIGH_BAND :
00161     if(Fc<860166667)
00162     {
00163       SpiritCalibrationSelectVco(VCO_L);
00164     }
00165     else
00166     {
00167       SpiritCalibrationSelectVco(VCO_H);
00168     }
00169   }
00170   
00171   /* Search the VCO charge pump word and set the corresponding register */
00172   wcp = SpiritRadioSearchWCP(Fc);
00173   
00174   synthWord = (uint32_t)(lFBase*(((double)(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band]))/SpiritRadioGetXtalFrequency()));
00175   
00176   /* Build the array of registers values for the analog part */
00177   anaRadioRegArray[0] = (uint8_t)(((synthWord>>21)&(0x0000001F))|(wcp<<5));
00178   anaRadioRegArray[1] = (uint8_t)((synthWord>>13)&(0x000000FF));
00179   anaRadioRegArray[2] = (uint8_t)((synthWord>>5)&(0x000000FF));
00180   anaRadioRegArray[3] = (uint8_t)(((synthWord&0x0000001F)<<3)| s_vectcBandRegValue[band]);
00181   
00182   /* Configures the needed Analog Radio registers */
00183   g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, anaRadioRegArray);
00184 }
00185 
00186 uint8_t SpiritManagementWaVcoCalibration(void)
00187 {
00188   uint8_t s_cVcoWordRx;
00189   uint8_t s_cVcoWordTx;
00190   uint32_t nFreq;
00191   uint8_t cRestore = 0;
00192   uint8_t cStandby = 0;
00193   uint32_t xtal_frequency = SpiritRadioGetXtalFrequency();
00194   
00195   /* Enable the reference divider if the XTAL is between 48 and 52 MHz */
00196   if(xtal_frequency>DOUBLE_XTAL_THR)
00197   {
00198     if(!SpiritRadioGetRefDiv())
00199     {
00200       cRestore = 1;
00201       nFreq = SpiritRadioGetFrequencyBase();
00202       SpiritRadioSetRefDiv(S_ENABLE);
00203       SpiritManagementSetFrequencyBase(nFreq);
00204     }
00205   }
00206   nFreq = SpiritRadioGetFrequencyBase();
00207   
00208   /* Increase the VCO current */
00209   uint8_t tmp = 0x19; SpiritSpiWriteRegisters(0xA1,1,&tmp);
00210   
00211   SpiritCalibrationVco(S_ENABLE);
00212   
00213   SpiritRefreshStatus();
00214   if(g_xStatus.MC_STATE == MC_STATE_STANDBY)
00215   {
00216     cStandby = 1;
00217     SpiritCmdStrobeReady();
00218     do{
00219       SpiritRefreshStatus();
00220       if(g_xStatus.MC_STATE == 0x13)
00221       {
00222         return 1;
00223       }
00224     }while(g_xStatus.MC_STATE != MC_STATE_READY); 
00225   }
00226   
00227   SpiritCmdStrobeLockTx();
00228   
00229   do{
00230     SpiritRefreshStatus();
00231     if(g_xStatus.MC_STATE == 0x13)
00232     {
00233       return 1;
00234     }
00235   }while(g_xStatus.MC_STATE != MC_STATE_LOCK);
00236   
00237   s_cVcoWordTx = SpiritCalibrationGetVcoCalData();
00238   
00239   SpiritCmdStrobeReady();
00240   
00241   do{
00242     SpiritRefreshStatus();
00243   }while(g_xStatus.MC_STATE != MC_STATE_READY); 
00244   
00245     
00246   SpiritCmdStrobeLockRx();
00247   
00248   do{
00249     SpiritRefreshStatus();
00250     if(g_xStatus.MC_STATE == 0x13)
00251     {
00252       return 1;
00253     }
00254   }while(g_xStatus.MC_STATE != MC_STATE_LOCK);
00255   
00256   s_cVcoWordRx = SpiritCalibrationGetVcoCalData();
00257   
00258   SpiritCmdStrobeReady();
00259   
00260   do{
00261     SpiritRefreshStatus();
00262     if(g_xStatus.MC_STATE == 0x13)
00263     {
00264       return 1;
00265     }
00266   }while(g_xStatus.MC_STATE != MC_STATE_READY);
00267   
00268   if(cStandby == 1)
00269   {
00270     SpiritCmdStrobeStandby();    
00271   }
00272   SpiritCalibrationVco(S_DISABLE);
00273   
00274   /* Disable the reference divider if the XTAL is between 48 and 52 MHz */
00275   if(cRestore)
00276   {
00277     SpiritRadioSetRefDiv(S_DISABLE);    
00278     SpiritManagementSetFrequencyBase(nFreq);
00279   }
00280   
00281   /* Restore the VCO current */
00282   tmp = 0x11; SpiritSpiWriteRegisters(0xA1,1,&tmp);
00283   
00284   SpiritCalibrationSetVcoCalDataTx(s_cVcoWordTx);
00285   SpiritCalibrationSetVcoCalDataRx(s_cVcoWordRx);
00286   
00287   return 0;
00288 }
00289 
00290 
00291 void SpiritManagementWaCmdStrobeTx(void)
00292 {
00293   if(s_cCommunicationState != COMMUNICATION_STATE_TX)
00294   {
00295     //uint32_t xtal_frequency = SpiritRadioGetXtalFrequency();
00296     
00297     /* To achive the max output power */
00298     if(s_nDesiredFrequency>=150000000 && s_nDesiredFrequency<=470000000)
00299     {
00300       /* Optimal setting for Tx mode only */
00301       SpiritRadioSetPACwc(LOAD_3_6_PF );
00302     }
00303     else
00304     {
00305       /* Optimal setting for Tx mode only */
00306       SpiritRadioSetPACwc(LOAD_0_PF );
00307     }
00308     
00309     uint8_t tmp = 0x11; SpiritSpiWriteRegisters(0xa9, 1, &tmp); /* Enable VCO_L buffer */
00310     tmp = 0x20; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */
00311     
00312     s_cCommunicationState = COMMUNICATION_STATE_TX;
00313   }
00314 }
00315 
00316 
00317 void SpiritManagementWaCmdStrobeRx(void)
00318 {
00319   if(s_cCommunicationState != COMMUNICATION_STATE_RX)
00320   {    
00321     uint8_t tmp = 0x98; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */    
00322     SpiritRadioSetPACwc(LOAD_0_PF ); /* Set the correct CWC parameter */
00323     
00324     s_cCommunicationState = COMMUNICATION_STATE_RX;
00325   }
00326 }
00327 
00328 void SpiritManagementWaTRxFcMem(uint32_t nDesiredFreq)
00329 {
00330   s_cCommunicationState = COMMUNICATION_STATE_NONE;
00331   s_nDesiredFrequency = nDesiredFreq;
00332 }
00333 
00334 
00335 void SpiritManagementWaExtraCurrent(void)
00336 {          
00337   uint8_t tmp= 0xCA;SpiritSpiWriteRegisters(0xB2, 1, &tmp); 
00338   tmp= 0x04;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 
00339   /* just a read to loose some microsecs more */
00340   SpiritSpiReadRegisters(0xA8, 1, &tmp);
00341   tmp= 0x00;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 
00342 }
00343 
00344 /**
00345 * @}
00346 */
00347 
00348 
00349 
00350 /**
00351 * @}
00352 */
00353 
00354 
00355 /**
00356 * @}
00357 */
00358 
00359 /**
00360 * @}
00361 */
00362 
00363 
00364 /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/