2020-10-18 22:09:48 +00:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* @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
|
|
|
|
*/
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/*! \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
|
2022-01-05 16:10:18 +00:00
|
|
|
#define RFAL_FEATURE_DPO \
|
|
|
|
false /* Dynamic Power Module configuration missing. Disabled by default */
|
2020-10-18 22:09:48 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RFAL_FEATURE_DPO
|
|
|
|
|
|
|
|
/*
|
|
|
|
******************************************************************************
|
|
|
|
* DEFINES
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
2022-01-05 16:10:18 +00:00
|
|
|
#define RFAL_DPO_ANALOGCONFIG_SHIFT 13U
|
|
|
|
#define RFAL_DPO_ANALOGCONFIG_MASK 0x6000U
|
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/*
|
|
|
|
******************************************************************************
|
|
|
|
* LOCAL DATA TYPES
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
2022-01-05 16:10:18 +00:00
|
|
|
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;
|
2020-10-18 22:09:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
******************************************************************************
|
|
|
|
* GLOBAL FUNCTIONS
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
2022-01-05 16:10:18 +00:00
|
|
|
void rfalDpoInitialize(void) {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Use the default Dynamic Power values */
|
2022-01-05 16:10:18 +00:00
|
|
|
gRfalCurrentDpo = (uint8_t*)rfalDpoDefaultSettings;
|
2020-10-18 22:09:48 +00:00
|
|
|
gRfalDpoTableEntries = (sizeof(rfalDpoDefaultSettings) / RFAL_DPO_TABLE_PARAMETER);
|
2022-01-05 16:10:18 +00:00
|
|
|
|
|
|
|
ST_MEMCPY(gRfalDpo, gRfalCurrentDpo, sizeof(rfalDpoDefaultSettings));
|
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* by default use amplitude measurement */
|
|
|
|
gRfalDpoMeasureCallback = rfalChipMeasureAmplitude;
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* by default DPO is disabled */
|
|
|
|
gRfalDpoIsEnabled = false;
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
gRfalDpoTableEntry = 0;
|
|
|
|
}
|
|
|
|
|
2022-01-05 16:10:18 +00:00
|
|
|
void rfalDpoSetMeasureCallback(rfalDpoMeasureFunc pMeasureFunc) {
|
|
|
|
gRfalDpoMeasureCallback = pMeasureFunc;
|
2020-10-18 22:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
ReturnCode rfalDpoTableWrite(rfalDpoEntry* powerTbl, uint8_t powerTblEntries) {
|
2020-10-18 22:09:48 +00:00
|
|
|
uint8_t entry = 0;
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* check if the table size parameter is too big */
|
2022-01-05 16:10:18 +00:00
|
|
|
if((powerTblEntries * RFAL_DPO_TABLE_PARAMETER) > RFAL_DPO_TABLE_SIZE_MAX) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_NOMEM;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* check if the first increase entry is 0xFF */
|
2022-01-05 16:10:18 +00:00
|
|
|
if((powerTblEntries == 0) || (powerTbl == NULL)) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_PARAM;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* check if the entries of the dynamic power table are valid */
|
2022-01-05 16:10:18 +00:00
|
|
|
for(entry = 0; entry < powerTblEntries; entry++) {
|
|
|
|
if(powerTbl[entry].inc < powerTbl[entry].dec) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_PARAM;
|
|
|
|
}
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* copy the data set */
|
2022-01-05 16:10:18 +00:00
|
|
|
ST_MEMCPY(gRfalDpo, powerTbl, (powerTblEntries * RFAL_DPO_TABLE_PARAMETER));
|
2020-10-18 22:09:48 +00:00
|
|
|
gRfalCurrentDpo = gRfalDpo;
|
|
|
|
gRfalDpoTableEntries = powerTblEntries;
|
2022-01-05 16:10:18 +00:00
|
|
|
|
|
|
|
if(gRfalDpoTableEntry > powerTblEntries) {
|
|
|
|
/* is always greater then zero, otherwise we already returned ERR_PARAM */
|
|
|
|
gRfalDpoTableEntry = (powerTblEntries - 1);
|
2020-10-18 22:09:48 +00:00
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
ReturnCode rfalDpoTableRead(rfalDpoEntry* tblBuf, uint8_t tblBufEntries, uint8_t* tableEntries) {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* wrong request */
|
2022-01-05 16:10:18 +00:00
|
|
|
if((tblBuf == NULL) || (tblBufEntries < gRfalDpoTableEntries) || (tableEntries == NULL)) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_PARAM;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Copy the whole Table to the given buffer */
|
2022-01-05 16:10:18 +00:00
|
|
|
ST_MEMCPY(tblBuf, gRfalCurrentDpo, (tblBufEntries * RFAL_DPO_TABLE_PARAMETER));
|
2020-10-18 22:09:48 +00:00
|
|
|
*tableEntries = gRfalDpoTableEntries;
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
ReturnCode rfalDpoAdjust(void) {
|
|
|
|
uint8_t refValue = 0;
|
|
|
|
uint16_t modeID;
|
2020-10-18 22:09:48 +00:00
|
|
|
rfalBitRate br;
|
2022-01-05 16:10:18 +00:00
|
|
|
rfalDpoEntry* dpoTable = (rfalDpoEntry*)gRfalCurrentDpo;
|
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Check if the Power Adjustment is disabled and *
|
|
|
|
* if the callback to the measurement method is properly set */
|
2022-01-05 16:10:18 +00:00
|
|
|
if((gRfalCurrentDpo == NULL) || (!gRfalDpoIsEnabled) || (gRfalDpoMeasureCallback == NULL)) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_PARAM;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Ensure that the current mode is Passive Poller */
|
2022-01-05 16:10:18 +00:00
|
|
|
if(!rfalIsModePassivePoll(rfalGetMode())) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_WRONG_STATE;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Ensure a proper measure reference value */
|
2022-01-05 16:10:18 +00:00
|
|
|
if(ERR_NONE != gRfalDpoMeasureCallback(&refValue)) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_IO;
|
|
|
|
}
|
|
|
|
|
2022-01-05 16:10:18 +00:00
|
|
|
if(refValue >= dpoTable[gRfalDpoTableEntry].inc) { /* Increase the output power */
|
2020-10-18 22:09:48 +00:00
|
|
|
/* the top of the table represents the highest amplitude value*/
|
2022-01-05 16:10:18 +00:00
|
|
|
if(gRfalDpoTableEntry == 0) {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* maximum driver value has been reached */
|
2022-01-05 16:10:18 +00:00
|
|
|
} else {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* go up in the table to decrease the driver resistance */
|
|
|
|
gRfalDpoTableEntry--;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
} else if(refValue <= dpoTable[gRfalDpoTableEntry].dec) { /* decrease the output power */
|
2020-10-18 22:09:48 +00:00
|
|
|
/* The bottom is the highest possible value */
|
2022-01-05 16:10:18 +00:00
|
|
|
if((gRfalDpoTableEntry + 1) >= gRfalDpoTableEntries) {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* minimum driver value has been reached */
|
2022-01-05 16:10:18 +00:00
|
|
|
} else {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* go down in the table to increase the driver resistance */
|
|
|
|
gRfalDpoTableEntry++;
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
} else {
|
2020-10-18 22:09:48 +00:00
|
|
|
/* Fall through to always write dpo and its associated analog configs */
|
|
|
|
}
|
2022-01-05 16:10:18 +00:00
|
|
|
|
|
|
|
/* Get the new value for RFO resistance form the table and apply the new RFO resistance setting */
|
|
|
|
rfalChipSetRFO(dpoTable[gRfalDpoTableEntry].rfoRes);
|
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
/* 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) */
|
2022-01-05 16:10:18 +00:00
|
|
|
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 */
|
|
|
|
|
2020-10-18 22:09:48 +00:00
|
|
|
return ERR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
rfalDpoEntry* rfalDpoGetCurrentTableEntry(void) {
|
|
|
|
rfalDpoEntry* dpoTable = (rfalDpoEntry*)gRfalCurrentDpo;
|
2020-10-18 22:09:48 +00:00
|
|
|
return &dpoTable[gRfalDpoTableEntry];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
void rfalDpoSetEnabled(bool enable) {
|
2020-10-18 22:09:48 +00:00
|
|
|
gRfalDpoIsEnabled = enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2022-01-05 16:10:18 +00:00
|
|
|
bool rfalDpoIsEnabled(void) {
|
2020-10-18 22:09:48 +00:00
|
|
|
return gRfalDpoIsEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* RFAL_FEATURE_DPO */
|