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 */
|