260 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| 
 | |
| /******************************************************************************
 | |
|   * @attention
 | |
|   *
 | |
|   * <h2><center>© COPYRIGHT 2020 STMicroelectronics</center></h2>
 | |
|   *
 | |
|   * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
 | |
|   * You may not use this file except in compliance with the License.
 | |
|   * You may obtain a copy of the License at:
 | |
|   *
 | |
|   *        http://www.st.com/myliberty
 | |
|   *
 | |
|   * Unless required by applicable law or agreed to in writing, software 
 | |
|   * distributed under the License is distributed on an "AS IS" BASIS, 
 | |
|   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
 | |
|   * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 | |
|   * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
 | |
|   * See the License for the specific language governing permissions and
 | |
|   * limitations under the License.
 | |
|   *
 | |
| ******************************************************************************/
 | |
| 
 | |
| /*
 | |
|  *      PROJECT:   ST25R391x firmware
 | |
|  *      $Revision: $
 | |
|  *      LANGUAGE:  ISO C99
 | |
|  */
 | |
|  
 | |
| /*! \file rfal_dpo.c
 | |
|  *
 | |
|  *  \author Martin Zechleitner
 | |
|  *
 | |
|  *  \brief Functions to manage and set dynamic power settings.
 | |
|  *  
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  ******************************************************************************
 | |
|  * INCLUDES
 | |
|  ******************************************************************************
 | |
|  */
 | |
| #include "rfal_dpoTbl.h"
 | |
| #include "rfal_dpo.h"
 | |
| #include "platform.h"
 | |
| #include "rfal_rf.h"
 | |
| #include "rfal_chip.h"
 | |
| #include "rfal_analogConfig.h"
 | |
| #include "utils.h"
 | |
| 
 | |
| 
 | |
| /*
 | |
|  ******************************************************************************
 | |
|  * ENABLE SWITCH
 | |
|  ******************************************************************************
 | |
|  */
 | |
| 
 | |
| #ifndef RFAL_FEATURE_DPO
 | |
|     #define RFAL_FEATURE_DPO   false    /* Dynamic Power Module configuration missing. Disabled by default */
 | |
| #endif
 | |
| 
 | |
| #if RFAL_FEATURE_DPO
 | |
| 
 | |
| 
 | |
| /*
 | |
|  ******************************************************************************
 | |
|  * DEFINES
 | |
|  ******************************************************************************
 | |
|  */
 | |
| #define RFAL_DPO_ANALOGCONFIG_SHIFT       13U
 | |
| #define RFAL_DPO_ANALOGCONFIG_MASK        0x6000U
 | |
|     
 | |
| /*
 | |
|  ******************************************************************************
 | |
|  * LOCAL DATA TYPES
 | |
|  ******************************************************************************
 | |
|  */
 | |
| 
 | |
| static bool                gRfalDpoIsEnabled = false;
 | |
| static uint8_t*            gRfalCurrentDpo;
 | |
| static uint8_t             gRfalDpoTableEntries;
 | |
| static uint8_t             gRfalDpo[RFAL_DPO_TABLE_SIZE_MAX];
 | |
| static uint8_t             gRfalDpoTableEntry;
 | |
| static rfalDpoMeasureFunc  gRfalDpoMeasureCallback = NULL;
 | |
| 
 | |
| /*
 | |
|  ******************************************************************************
 | |
|  * GLOBAL FUNCTIONS
 | |
|  ******************************************************************************
 | |
|  */
 | |
| void rfalDpoInitialize( void )
 | |
| {
 | |
|     /* Use the default Dynamic Power values */
 | |
|     gRfalCurrentDpo = (uint8_t*) rfalDpoDefaultSettings;
 | |
|     gRfalDpoTableEntries = (sizeof(rfalDpoDefaultSettings) / RFAL_DPO_TABLE_PARAMETER);
 | |
|     
 | |
|     ST_MEMCPY( gRfalDpo, gRfalCurrentDpo, sizeof(rfalDpoDefaultSettings) );
 | |
|     
 | |
|     /* by default use amplitude measurement */
 | |
|     gRfalDpoMeasureCallback = rfalChipMeasureAmplitude;
 | |
|     
 | |
|     /* by default DPO is disabled */
 | |
|     gRfalDpoIsEnabled = false;
 | |
|     
 | |
|     gRfalDpoTableEntry = 0;
 | |
| }
 | |
| 
 | |
| void rfalDpoSetMeasureCallback( rfalDpoMeasureFunc pMeasureFunc )
 | |
| {
 | |
|   gRfalDpoMeasureCallback = pMeasureFunc;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| ReturnCode rfalDpoTableWrite( rfalDpoEntry* powerTbl, uint8_t powerTblEntries )
 | |
| {
 | |
|     uint8_t entry = 0;
 | |
|     
 | |
|     /* check if the table size parameter is too big */
 | |
|     if( (powerTblEntries * RFAL_DPO_TABLE_PARAMETER) > RFAL_DPO_TABLE_SIZE_MAX)
 | |
|     {
 | |
|         return ERR_NOMEM;
 | |
|     }
 | |
|     
 | |
|     /* check if the first increase entry is 0xFF */
 | |
|     if( (powerTblEntries == 0) || (powerTbl == NULL) )
 | |
|     {
 | |
|         return ERR_PARAM;
 | |
|     }
 | |
|                 
 | |
|     /* check if the entries of the dynamic power table are valid */
 | |
|     for (entry = 0; entry < powerTblEntries; entry++)
 | |
|     {
 | |
|         if(powerTbl[entry].inc < powerTbl[entry].dec)
 | |
|         {
 | |
|             return ERR_PARAM;
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /* copy the data set  */
 | |
|     ST_MEMCPY( gRfalDpo, powerTbl, (powerTblEntries * RFAL_DPO_TABLE_PARAMETER) );
 | |
|     gRfalCurrentDpo = gRfalDpo;
 | |
|     gRfalDpoTableEntries = powerTblEntries;
 | |
|     
 | |
|     if(gRfalDpoTableEntry > powerTblEntries)
 | |
|     {
 | |
|       /* is always greater then zero, otherwise we already returned ERR_PARAM */
 | |
|       gRfalDpoTableEntry = (powerTblEntries - 1); 
 | |
|     }
 | |
|     
 | |
|     return ERR_NONE;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| ReturnCode rfalDpoTableRead( rfalDpoEntry* tblBuf, uint8_t tblBufEntries, uint8_t* tableEntries )
 | |
| {
 | |
|     /* wrong request */
 | |
|     if( (tblBuf == NULL) || (tblBufEntries < gRfalDpoTableEntries) || (tableEntries == NULL) )
 | |
|     {
 | |
|         return ERR_PARAM;
 | |
|     }
 | |
|         
 | |
|     /* Copy the whole Table to the given buffer */
 | |
|     ST_MEMCPY( tblBuf, gRfalCurrentDpo, (tblBufEntries * RFAL_DPO_TABLE_PARAMETER) );
 | |
|     *tableEntries = gRfalDpoTableEntries;
 | |
|     
 | |
|     return ERR_NONE;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| ReturnCode rfalDpoAdjust( void )
 | |
| {
 | |
|     uint8_t     refValue = 0;
 | |
|     uint16_t    modeID;
 | |
|     rfalBitRate br;
 | |
|     rfalDpoEntry* dpoTable = (rfalDpoEntry*) gRfalCurrentDpo;    
 | |
|     
 | |
|     /* Check if the Power Adjustment is disabled and                  *
 | |
|      * if the callback to the measurement method is properly set      */
 | |
|     if( (gRfalCurrentDpo == NULL) || (!gRfalDpoIsEnabled) || (gRfalDpoMeasureCallback == NULL) )
 | |
|     {
 | |
|         return ERR_PARAM;
 | |
|     }
 | |
|     
 | |
|     /* Ensure that the current mode is Passive Poller */
 | |
|     if( !rfalIsModePassivePoll( rfalGetMode() ) )
 | |
|     {
 | |
|         return ERR_WRONG_STATE;
 | |
|     }
 | |
|       
 | |
|     /* Ensure a proper measure reference value */
 | |
|     if( ERR_NONE != gRfalDpoMeasureCallback( &refValue ) )
 | |
|     {
 | |
|         return ERR_IO;
 | |
|     }
 | |
| 
 | |
|     
 | |
|     if( refValue >= dpoTable[gRfalDpoTableEntry].inc )
 | |
|     { /* Increase the output power */
 | |
|         /* the top of the table represents the highest amplitude value*/
 | |
|         if( gRfalDpoTableEntry == 0 )
 | |
|         {
 | |
|             /* maximum driver value has been reached */
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* go up in the table to decrease the driver resistance */
 | |
|             gRfalDpoTableEntry--;
 | |
|         }
 | |
|     }
 | |
|     else if(refValue <= dpoTable[gRfalDpoTableEntry].dec)
 | |
|     { /* decrease the output power */
 | |
|         /* The bottom is the highest possible value */
 | |
|         if( (gRfalDpoTableEntry + 1) >= gRfalDpoTableEntries)
 | |
|         {
 | |
|             /* minimum driver value has been reached */
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* go down in the table to increase the driver resistance */
 | |
|             gRfalDpoTableEntry++;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* Fall through to always write dpo and its associated analog configs */
 | |
|     }
 | |
|     
 | |
|     /* Get the new value for RFO resistance form the table and apply the new RFO resistance setting */ 
 | |
|     rfalChipSetRFO( dpoTable[gRfalDpoTableEntry].rfoRes );
 | |
|     
 | |
|     /* Apply the DPO Analog Config according to this treshold */
 | |
|     /* Technology field is being extended for DPO: 2msb are used for treshold step (only 4 allowed) */
 | |
|     rfalGetBitRate( &br, NULL );                                                                    /* Obtain current Tx bitrate       */
 | |
|     modeID  = rfalAnalogConfigGenModeID( rfalGetMode(), br, RFAL_ANALOG_CONFIG_DPO );               /* Generate Analog Config mode ID  */
 | |
|     modeID |= ((gRfalDpoTableEntry << RFAL_DPO_ANALOGCONFIG_SHIFT) & RFAL_DPO_ANALOGCONFIG_MASK);   /* Add DPO treshold step|level     */
 | |
|     rfalSetAnalogConfig( modeID );                                                                  /* Apply DPO Analog Config         */
 | |
|     
 | |
|     return ERR_NONE;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| rfalDpoEntry* rfalDpoGetCurrentTableEntry( void )
 | |
| {
 | |
|     rfalDpoEntry* dpoTable = (rfalDpoEntry*) gRfalCurrentDpo; 
 | |
|     return &dpoTable[gRfalDpoTableEntry];
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| void rfalDpoSetEnabled( bool enable )
 | |
| {
 | |
|     gRfalDpoIsEnabled = enable;
 | |
| }
 | |
| 
 | |
| /*******************************************************************************/
 | |
| bool rfalDpoIsEnabled( void )
 | |
| {
 | |
|     return gRfalDpoIsEnabled;
 | |
| }
 | |
| 
 | |
| #endif /* RFAL_FEATURE_DPO */
 |