| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /******************************************************************************
- * \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:
- *
- * 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: ST25R3916 firmware
- * Revision:
- * LANGUAGE: ISO C99
- */
- /*! \file st25r3916_aat.c
- *
- * \author
- *
- * \brief ST25R3916 Antenna Tuning
- *
- * The antenna tuning algorithm tries to find the optimal settings for
- * the AAT_A and AAT_B registers, which are connected to variable capacitors
- * to tune the antenna matching.
- *
- */
-
-
- /*
- ******************************************************************************
- * INCLUDES
- ******************************************************************************
- */
- #include "st25r3916_aat.h"
- #include "utils.h"
- #include "st_errno.h"
- #include "st25r3916.h"
- #include "st25r3916_com.h"
- #include "platform.h"
- #include "rfal_chip.h"
- /*
- ******************************************************************************
- * GLOBAL DEFINES
- ******************************************************************************
- */
- #define ST25R3916_AAT_CAP_DELAY_MAX 10 /*!< Max Variable Capacitor settle delay */
- /*
- ******************************************************************************
- * GLOBAL MACROS
- ******************************************************************************
- */
- #define st25r3916AatLog(...) /* platformLog(__VA_ARGS__) */ /*!< Logging macro */
- /*
- ******************************************************************************
- * LOCAL FUNCTION PROTOTYPES
- ******************************************************************************
- */
- static ReturnCode aatHillClimb(const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus);
- static int32_t aatGreedyDescent(uint32_t *f_min, const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus, int32_t previousDir);
- static int32_t aatSteepestDescent(uint32_t *f_min, const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus, int32_t previousDir, int32_t previousDir2);
- static ReturnCode aatMeasure(uint8_t serCap, uint8_t parCap, uint8_t *amplitude, uint8_t *phase, uint16_t *measureCnt);
- static uint32_t aatCalcF(const struct st25r3916AatTuneParams *tuningParams, uint8_t amplitude, uint8_t phase);
- static ReturnCode aatStepDacVals(const struct st25r3916AatTuneParams *tuningParams,uint8_t *a, uint8_t *b, int32_t dir);
-
- /*******************************************************************************/
- ReturnCode st25r3916AatTune(const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus)
- {
- ReturnCode err;
- const struct st25r3916AatTuneParams *tp = tuningParams;
- struct st25r3916AatTuneResult *ts = tuningStatus;
- struct st25r3916AatTuneParams defaultTuningParams =
- {
- .aat_a_min=0,
- .aat_a_max=255,
- .aat_a_start=127,
- .aat_a_stepWidth=32,
- .aat_b_min=0,
- .aat_b_max=255,
- .aat_b_start=127,
- .aat_b_stepWidth=32,
- .phaTarget=128,
- .phaWeight=2,
- .ampTarget=196,
- .ampWeight=1,
- .doDynamicSteps=true,
- .measureLimit=50,
- };
- struct st25r3916AatTuneResult defaultTuneResult;
-
- if ((NULL != tp) && (
- (tp->aat_a_min > tp->aat_a_max )
- || (tp->aat_a_start < tp->aat_a_min )
- || (tp->aat_a_start > tp->aat_a_max )
- || (tp->aat_b_min > tp->aat_b_max )
- || (tp->aat_b_start < tp->aat_b_min )
- || (tp->aat_b_start > tp->aat_b_max )
- ))
- {
- return ERR_PARAM;
- }
- if (NULL == tp)
- { /* Start from current caps with default params */
- st25r3916ReadRegister(ST25R3916_REG_ANT_TUNE_A, &defaultTuningParams.aat_a_start);
- st25r3916ReadRegister(ST25R3916_REG_ANT_TUNE_B, &defaultTuningParams.aat_b_start);
- tp = &defaultTuningParams;
- }
- if (NULL == ts){ts = &defaultTuneResult;}
- ts->measureCnt = 0; /* Clear current measure count */
-
- err = aatHillClimb(tp, ts);
- return err;
- }
- /*******************************************************************************/
- static ReturnCode aatHillClimb(const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus)
- {
- ReturnCode err = ERR_NONE;
- uint32_t f_min;
- int32_t direction, gdirection;
- uint8_t amp,phs;
- struct st25r3916AatTuneParams tp = *tuningParams; // local copy to obey const
- tuningStatus->aat_a = tuningParams->aat_a_start;
- tuningStatus->aat_b = tuningParams->aat_b_start;
- /* Get a proper start value */
- aatMeasure(tuningStatus->aat_a,tuningStatus->aat_b,&,&phs,&tuningStatus->measureCnt);
- f_min = aatCalcF(&tp, amp, phs);
- direction = 0;
- st25r3916AatLog("%d %d: %d***\n",tuningStatus->aat_a,tuningStatus->aat_b,f_min);
- do {
- direction = 0; /* Initially and after reducing step sizes we don't have a previous direction */
- do {
- /* With the greedy step below always executed aftwards the -direction does never need to be investigated */
- direction = aatSteepestDescent(&f_min, &tp, tuningStatus, direction, -direction);
- if (tuningStatus->measureCnt > tp.measureLimit)
- {
- err = ERR_OVERRUN;
- break;
- }
- do
- {
- gdirection = aatGreedyDescent(&f_min, &tp, tuningStatus, direction);
- if (tuningStatus->measureCnt > tp.measureLimit) {
- err = ERR_OVERRUN;
- break;
- }
- } while (0 != gdirection);
- } while (0 != direction);
- tp.aat_a_stepWidth /= 2U; /* Reduce step sizes */
- tp.aat_b_stepWidth /= 2U;
- } while (tp.doDynamicSteps && ((tp.aat_a_stepWidth>0U) || (tp.aat_b_stepWidth>0U)));
-
- return err;
- }
- /*******************************************************************************/
- static int32_t aatSteepestDescent(uint32_t *f_min, const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus, int32_t previousDir, int32_t previousDir2)
- {
- int32_t i;
- uint8_t amp,phs;
- uint32_t f;
- int32_t bestdir = 0; /* Negative direction: decrease, Positive: increase. (-)1: aat_a, (-)2: aat_b */
- for (i = -2; i <= 2; i++)
- {
- uint8_t a = tuningStatus->aat_a , b = tuningStatus->aat_b;
- if ((0==i) || (i==-previousDir) || (i==-previousDir2))
- { /* Skip no direction and avoid going backwards */
- continue;
- }
- if (0U!=aatStepDacVals(tuningParams, &a, &b, i))
- { /* If stepping did not change the value, omit this direction */
- continue;
- }
- aatMeasure(a,b,&,&phs,&tuningStatus->measureCnt);
- f = aatCalcF(tuningParams, amp, phs);
- st25r3916AatLog("%d : %d %d: %d",i,a, b, f);
- if (f < *f_min)
- { /* Value is better than all previous ones */
- st25r3916AatLog("*");
- *f_min = f;
- bestdir = i;
- }
- st25r3916AatLog("\n");
- }
- if (0!=bestdir)
- { /* Walk into the best direction */
- aatStepDacVals(tuningParams, &tuningStatus->aat_a, &tuningStatus->aat_b, bestdir);
- }
- return bestdir;
- }
- /*******************************************************************************/
- static int32_t aatGreedyDescent(uint32_t *f_min, const struct st25r3916AatTuneParams *tuningParams, struct st25r3916AatTuneResult *tuningStatus, int32_t previousDir)
- {
- uint8_t amp,phs;
- uint32_t f;
- uint8_t a = tuningStatus->aat_a , b = tuningStatus->aat_b;
- if (0U != aatStepDacVals(tuningParams, &a, &b, previousDir))
- { /* If stepping did not change the value, omit this direction */
- return 0;
- }
- aatMeasure(a,b,&,&phs,&tuningStatus->measureCnt);
- f = aatCalcF(tuningParams, amp, phs);
- st25r3916AatLog("g : %d %d: %d",a, b, f);
- if (f < *f_min)
- { /* Value is better than previous one */
- st25r3916AatLog("*\n");
- tuningStatus->aat_a = a;
- tuningStatus->aat_b = b;
- *f_min = f;
- return previousDir;
- }
-
- st25r3916AatLog("\n");
- return 0;
- }
- /*******************************************************************************/
- static uint32_t aatCalcF(const struct st25r3916AatTuneParams *tuningParams, uint8_t amplitude, uint8_t phase)
- {
- /* f(amp, pha) = (ampWeight * |amp - ampTarget|) + (phaWeight * |pha - phaTarget|) */
- uint8_t ampTarget = tuningParams->ampTarget;
- uint8_t phaTarget = tuningParams->phaTarget;
- uint32_t ampWeight = tuningParams->ampWeight;
- uint32_t phaWeight = tuningParams->phaWeight;
- /* Temp variables to avoid MISRA R10.8 (cast on composite expression) */
- uint8_t ad = ((amplitude > ampTarget) ? (amplitude - ampTarget) : (ampTarget - amplitude));
- uint8_t pd = ((phase > phaTarget) ? (phase - phaTarget) : (phaTarget - phase));
- uint32_t ampDelta = (uint32_t)ad;
- uint32_t phaDelta = (uint32_t)pd;
- return ((ampWeight * ampDelta) + (phaWeight * phaDelta));
- }
- /*******************************************************************************/
- static ReturnCode aatStepDacVals(const struct st25r3916AatTuneParams *tuningParams,uint8_t *a, uint8_t *b, int32_t dir)
- {
- int16_t aat_a = (int16_t)*a, aat_b = (int16_t)*b;
-
- switch (abs(dir))
- { /* Advance by steps size in requested direction */
- case 1:
- aat_a = (dir<0)?(aat_a - (int16_t)tuningParams->aat_a_stepWidth):(aat_a + (int16_t)tuningParams->aat_a_stepWidth);
- if(aat_a < (int16_t)tuningParams->aat_a_min){ aat_a = (int16_t)tuningParams->aat_a_min; }
- if(aat_a > (int16_t)tuningParams->aat_a_max){ aat_a = (int16_t)tuningParams->aat_a_max; }
- if ((int16_t)*a == aat_a) {return ERR_PARAM;}
- break;
- case 2:
- aat_b = (dir<0)?(aat_b - (int16_t)tuningParams->aat_b_stepWidth):(aat_b + (int16_t)tuningParams->aat_b_stepWidth);
- if(aat_b < (int16_t)tuningParams->aat_b_min){ aat_b = (int16_t)tuningParams->aat_b_min; }
- if(aat_b > (int16_t)tuningParams->aat_b_max){ aat_b = (int16_t)tuningParams->aat_b_max; }
- if ((int16_t)*b == aat_b) {return ERR_PARAM;}
- break;
- default:
- return ERR_REQUEST;
- }
- /* We only get here if actual values have changed. In all other cases an error is returned */
- *a = (uint8_t)aat_a;
- *b = (uint8_t)aat_b;
-
- return ERR_NONE;
- }
- /*******************************************************************************/
- static ReturnCode aatMeasure(uint8_t serCap, uint8_t parCap, uint8_t *amplitude, uint8_t *phase, uint16_t *measureCnt)
- {
- ReturnCode err;
- *amplitude = 0;
- *phase = 0;
- st25r3916WriteRegister(ST25R3916_REG_ANT_TUNE_A, serCap);
- st25r3916WriteRegister(ST25R3916_REG_ANT_TUNE_B, parCap);
- /* Wait till caps have settled.. */
- platformDelay( ST25R3916_AAT_CAP_DELAY_MAX );
-
- /* Get amplitude and phase .. */
- err = rfalChipMeasureAmplitude(amplitude);
- if (ERR_NONE == err)
- {
- err = rfalChipMeasurePhase(phase);
- }
-
- if( measureCnt != NULL )
- {
- (*measureCnt)++;
- }
- return err;
- }
|