| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /******************************************************************************
- * \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;
- }
|