rfal_dpo.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /******************************************************************************
  2. * @attention
  3. *
  4. * <h2><center>&copy; COPYRIGHT 2020 STMicroelectronics</center></h2>
  5. *
  6. * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
  7. * You may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at:
  9. *
  10. * http://www.st.com/myliberty
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  15. * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. ******************************************************************************/
  21. /*
  22. * PROJECT: ST25R391x firmware
  23. * $Revision: $
  24. * LANGUAGE: ISO C99
  25. */
  26. /*! \file rfal_dpo.c
  27. *
  28. * \author Martin Zechleitner
  29. *
  30. * \brief Functions to manage and set dynamic power settings.
  31. *
  32. */
  33. /*
  34. ******************************************************************************
  35. * INCLUDES
  36. ******************************************************************************
  37. */
  38. #include "st25r3916/rfal_dpoTbl.h"
  39. #include "../include/rfal_dpo.h"
  40. #include "../platform.h"
  41. #include "../include/rfal_rf.h"
  42. #include "../include/rfal_chip.h"
  43. #include "../include/rfal_analogConfig.h"
  44. #include "../utils.h"
  45. /*
  46. ******************************************************************************
  47. * ENABLE SWITCH
  48. ******************************************************************************
  49. */
  50. #ifndef RFAL_FEATURE_DPO
  51. #define RFAL_FEATURE_DPO \
  52. false /* Dynamic Power Module configuration missing. Disabled by default */
  53. #endif
  54. #if RFAL_FEATURE_DPO
  55. /*
  56. ******************************************************************************
  57. * DEFINES
  58. ******************************************************************************
  59. */
  60. #define RFAL_DPO_ANALOGCONFIG_SHIFT 13U
  61. #define RFAL_DPO_ANALOGCONFIG_MASK 0x6000U
  62. /*
  63. ******************************************************************************
  64. * LOCAL DATA TYPES
  65. ******************************************************************************
  66. */
  67. static bool gRfalDpoIsEnabled = false;
  68. static uint8_t* gRfalCurrentDpo;
  69. static uint8_t gRfalDpoTableEntries;
  70. static uint8_t gRfalDpo[RFAL_DPO_TABLE_SIZE_MAX];
  71. static uint8_t gRfalDpoTableEntry;
  72. static rfalDpoMeasureFunc gRfalDpoMeasureCallback = NULL;
  73. /*
  74. ******************************************************************************
  75. * GLOBAL FUNCTIONS
  76. ******************************************************************************
  77. */
  78. void rfalDpoInitialize(void) {
  79. /* Use the default Dynamic Power values */
  80. gRfalCurrentDpo = (uint8_t*)rfalDpoDefaultSettings;
  81. gRfalDpoTableEntries = (sizeof(rfalDpoDefaultSettings) / RFAL_DPO_TABLE_PARAMETER);
  82. ST_MEMCPY(gRfalDpo, gRfalCurrentDpo, sizeof(rfalDpoDefaultSettings));
  83. /* by default use amplitude measurement */
  84. gRfalDpoMeasureCallback = rfalChipMeasureAmplitude;
  85. /* by default DPO is disabled */
  86. gRfalDpoIsEnabled = false;
  87. gRfalDpoTableEntry = 0;
  88. }
  89. void rfalDpoSetMeasureCallback(rfalDpoMeasureFunc pMeasureFunc) {
  90. gRfalDpoMeasureCallback = pMeasureFunc;
  91. }
  92. /*******************************************************************************/
  93. ReturnCode rfalDpoTableWrite(rfalDpoEntry* powerTbl, uint8_t powerTblEntries) {
  94. uint8_t entry = 0;
  95. /* check if the table size parameter is too big */
  96. if((powerTblEntries * RFAL_DPO_TABLE_PARAMETER) > RFAL_DPO_TABLE_SIZE_MAX) {
  97. return ERR_NOMEM;
  98. }
  99. /* check if the first increase entry is 0xFF */
  100. if((powerTblEntries == 0) || (powerTbl == NULL)) {
  101. return ERR_PARAM;
  102. }
  103. /* check if the entries of the dynamic power table are valid */
  104. for(entry = 0; entry < powerTblEntries; entry++) {
  105. if(powerTbl[entry].inc < powerTbl[entry].dec) {
  106. return ERR_PARAM;
  107. }
  108. }
  109. /* copy the data set */
  110. ST_MEMCPY(gRfalDpo, powerTbl, (powerTblEntries * RFAL_DPO_TABLE_PARAMETER));
  111. gRfalCurrentDpo = gRfalDpo;
  112. gRfalDpoTableEntries = powerTblEntries;
  113. if(gRfalDpoTableEntry > powerTblEntries) {
  114. /* is always greater then zero, otherwise we already returned ERR_PARAM */
  115. gRfalDpoTableEntry = (powerTblEntries - 1);
  116. }
  117. return ERR_NONE;
  118. }
  119. /*******************************************************************************/
  120. ReturnCode rfalDpoTableRead(rfalDpoEntry* tblBuf, uint8_t tblBufEntries, uint8_t* tableEntries) {
  121. /* wrong request */
  122. if((tblBuf == NULL) || (tblBufEntries < gRfalDpoTableEntries) || (tableEntries == NULL)) {
  123. return ERR_PARAM;
  124. }
  125. /* Copy the whole Table to the given buffer */
  126. ST_MEMCPY(tblBuf, gRfalCurrentDpo, (tblBufEntries * RFAL_DPO_TABLE_PARAMETER));
  127. *tableEntries = gRfalDpoTableEntries;
  128. return ERR_NONE;
  129. }
  130. /*******************************************************************************/
  131. ReturnCode rfalDpoAdjust(void) {
  132. uint8_t refValue = 0;
  133. uint16_t modeID;
  134. rfalBitRate br;
  135. rfalDpoEntry* dpoTable = (rfalDpoEntry*)gRfalCurrentDpo;
  136. /* Check if the Power Adjustment is disabled and *
  137. * if the callback to the measurement method is properly set */
  138. if((gRfalCurrentDpo == NULL) || (!gRfalDpoIsEnabled) || (gRfalDpoMeasureCallback == NULL)) {
  139. return ERR_PARAM;
  140. }
  141. /* Ensure that the current mode is Passive Poller */
  142. if(!rfalIsModePassivePoll(rfalGetMode())) {
  143. return ERR_WRONG_STATE;
  144. }
  145. /* Ensure a proper measure reference value */
  146. if(ERR_NONE != gRfalDpoMeasureCallback(&refValue)) {
  147. return ERR_IO;
  148. }
  149. if(refValue >= dpoTable[gRfalDpoTableEntry].inc) { /* Increase the output power */
  150. /* the top of the table represents the highest amplitude value*/
  151. if(gRfalDpoTableEntry == 0) {
  152. /* maximum driver value has been reached */
  153. } else {
  154. /* go up in the table to decrease the driver resistance */
  155. gRfalDpoTableEntry--;
  156. }
  157. } else if(refValue <= dpoTable[gRfalDpoTableEntry].dec) { /* decrease the output power */
  158. /* The bottom is the highest possible value */
  159. if((gRfalDpoTableEntry + 1) >= gRfalDpoTableEntries) {
  160. /* minimum driver value has been reached */
  161. } else {
  162. /* go down in the table to increase the driver resistance */
  163. gRfalDpoTableEntry++;
  164. }
  165. } else {
  166. /* Fall through to always write dpo and its associated analog configs */
  167. }
  168. /* Get the new value for RFO resistance form the table and apply the new RFO resistance setting */
  169. rfalChipSetRFO(dpoTable[gRfalDpoTableEntry].rfoRes);
  170. /* Apply the DPO Analog Config according to this treshold */
  171. /* Technology field is being extended for DPO: 2msb are used for treshold step (only 4 allowed) */
  172. rfalGetBitRate(&br, NULL); /* Obtain current Tx bitrate */
  173. modeID = rfalAnalogConfigGenModeID(
  174. rfalGetMode(), br, RFAL_ANALOG_CONFIG_DPO); /* Generate Analog Config mode ID */
  175. modeID |=
  176. ((gRfalDpoTableEntry << RFAL_DPO_ANALOGCONFIG_SHIFT) &
  177. RFAL_DPO_ANALOGCONFIG_MASK); /* Add DPO treshold step|level */
  178. rfalSetAnalogConfig(modeID); /* Apply DPO Analog Config */
  179. return ERR_NONE;
  180. }
  181. /*******************************************************************************/
  182. rfalDpoEntry* rfalDpoGetCurrentTableEntry(void) {
  183. rfalDpoEntry* dpoTable = (rfalDpoEntry*)gRfalCurrentDpo;
  184. return &dpoTable[gRfalDpoTableEntry];
  185. }
  186. /*******************************************************************************/
  187. void rfalDpoSetEnabled(bool enable) {
  188. gRfalDpoIsEnabled = enable;
  189. }
  190. /*******************************************************************************/
  191. bool rfalDpoIsEnabled(void) {
  192. return gRfalDpoIsEnabled;
  193. }
  194. #endif /* RFAL_FEATURE_DPO */