rfal_dpo.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 "rfal_dpoTbl.h"
  39. #include "rfal_dpo.h"
  40. #include "platform.h"
  41. #include "rfal_rf.h"
  42. #include "rfal_chip.h"
  43. #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 false /* Dynamic Power Module configuration missing. Disabled by default */
  52. #endif
  53. #if RFAL_FEATURE_DPO
  54. /*
  55. ******************************************************************************
  56. * DEFINES
  57. ******************************************************************************
  58. */
  59. #define RFAL_DPO_ANALOGCONFIG_SHIFT 13U
  60. #define RFAL_DPO_ANALOGCONFIG_MASK 0x6000U
  61. /*
  62. ******************************************************************************
  63. * LOCAL DATA TYPES
  64. ******************************************************************************
  65. */
  66. static bool gRfalDpoIsEnabled = false;
  67. static uint8_t* gRfalCurrentDpo;
  68. static uint8_t gRfalDpoTableEntries;
  69. static uint8_t gRfalDpo[RFAL_DPO_TABLE_SIZE_MAX];
  70. static uint8_t gRfalDpoTableEntry;
  71. static rfalDpoMeasureFunc gRfalDpoMeasureCallback = NULL;
  72. /*
  73. ******************************************************************************
  74. * GLOBAL FUNCTIONS
  75. ******************************************************************************
  76. */
  77. void rfalDpoInitialize( void )
  78. {
  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. {
  91. gRfalDpoMeasureCallback = pMeasureFunc;
  92. }
  93. /*******************************************************************************/
  94. ReturnCode rfalDpoTableWrite( rfalDpoEntry* powerTbl, uint8_t powerTblEntries )
  95. {
  96. uint8_t entry = 0;
  97. /* check if the table size parameter is too big */
  98. if( (powerTblEntries * RFAL_DPO_TABLE_PARAMETER) > RFAL_DPO_TABLE_SIZE_MAX)
  99. {
  100. return ERR_NOMEM;
  101. }
  102. /* check if the first increase entry is 0xFF */
  103. if( (powerTblEntries == 0) || (powerTbl == NULL) )
  104. {
  105. return ERR_PARAM;
  106. }
  107. /* check if the entries of the dynamic power table are valid */
  108. for (entry = 0; entry < powerTblEntries; entry++)
  109. {
  110. if(powerTbl[entry].inc < powerTbl[entry].dec)
  111. {
  112. return ERR_PARAM;
  113. }
  114. }
  115. /* copy the data set */
  116. ST_MEMCPY( gRfalDpo, powerTbl, (powerTblEntries * RFAL_DPO_TABLE_PARAMETER) );
  117. gRfalCurrentDpo = gRfalDpo;
  118. gRfalDpoTableEntries = powerTblEntries;
  119. if(gRfalDpoTableEntry > powerTblEntries)
  120. {
  121. /* is always greater then zero, otherwise we already returned ERR_PARAM */
  122. gRfalDpoTableEntry = (powerTblEntries - 1);
  123. }
  124. return ERR_NONE;
  125. }
  126. /*******************************************************************************/
  127. ReturnCode rfalDpoTableRead( rfalDpoEntry* tblBuf, uint8_t tblBufEntries, uint8_t* tableEntries )
  128. {
  129. /* wrong request */
  130. if( (tblBuf == NULL) || (tblBufEntries < gRfalDpoTableEntries) || (tableEntries == NULL) )
  131. {
  132. return ERR_PARAM;
  133. }
  134. /* Copy the whole Table to the given buffer */
  135. ST_MEMCPY( tblBuf, gRfalCurrentDpo, (tblBufEntries * RFAL_DPO_TABLE_PARAMETER) );
  136. *tableEntries = gRfalDpoTableEntries;
  137. return ERR_NONE;
  138. }
  139. /*******************************************************************************/
  140. ReturnCode rfalDpoAdjust( void )
  141. {
  142. uint8_t refValue = 0;
  143. uint16_t modeID;
  144. rfalBitRate br;
  145. rfalDpoEntry* dpoTable = (rfalDpoEntry*) gRfalCurrentDpo;
  146. /* Check if the Power Adjustment is disabled and *
  147. * if the callback to the measurement method is properly set */
  148. if( (gRfalCurrentDpo == NULL) || (!gRfalDpoIsEnabled) || (gRfalDpoMeasureCallback == NULL) )
  149. {
  150. return ERR_PARAM;
  151. }
  152. /* Ensure that the current mode is Passive Poller */
  153. if( !rfalIsModePassivePoll( rfalGetMode() ) )
  154. {
  155. return ERR_WRONG_STATE;
  156. }
  157. /* Ensure a proper measure reference value */
  158. if( ERR_NONE != gRfalDpoMeasureCallback( &refValue ) )
  159. {
  160. return ERR_IO;
  161. }
  162. if( refValue >= dpoTable[gRfalDpoTableEntry].inc )
  163. { /* Increase the output power */
  164. /* the top of the table represents the highest amplitude value*/
  165. if( gRfalDpoTableEntry == 0 )
  166. {
  167. /* maximum driver value has been reached */
  168. }
  169. else
  170. {
  171. /* go up in the table to decrease the driver resistance */
  172. gRfalDpoTableEntry--;
  173. }
  174. }
  175. else if(refValue <= dpoTable[gRfalDpoTableEntry].dec)
  176. { /* decrease the output power */
  177. /* The bottom is the highest possible value */
  178. if( (gRfalDpoTableEntry + 1) >= gRfalDpoTableEntries)
  179. {
  180. /* minimum driver value has been reached */
  181. }
  182. else
  183. {
  184. /* go down in the table to increase the driver resistance */
  185. gRfalDpoTableEntry++;
  186. }
  187. }
  188. else
  189. {
  190. /* Fall through to always write dpo and its associated analog configs */
  191. }
  192. /* Get the new value for RFO resistance form the table and apply the new RFO resistance setting */
  193. rfalChipSetRFO( dpoTable[gRfalDpoTableEntry].rfoRes );
  194. /* Apply the DPO Analog Config according to this treshold */
  195. /* Technology field is being extended for DPO: 2msb are used for treshold step (only 4 allowed) */
  196. rfalGetBitRate( &br, NULL ); /* Obtain current Tx bitrate */
  197. modeID = rfalAnalogConfigGenModeID( rfalGetMode(), br, RFAL_ANALOG_CONFIG_DPO ); /* Generate Analog Config mode ID */
  198. modeID |= ((gRfalDpoTableEntry << RFAL_DPO_ANALOGCONFIG_SHIFT) & RFAL_DPO_ANALOGCONFIG_MASK); /* Add DPO treshold step|level */
  199. rfalSetAnalogConfig( modeID ); /* Apply DPO Analog Config */
  200. return ERR_NONE;
  201. }
  202. /*******************************************************************************/
  203. rfalDpoEntry* rfalDpoGetCurrentTableEntry( void )
  204. {
  205. rfalDpoEntry* dpoTable = (rfalDpoEntry*) gRfalCurrentDpo;
  206. return &dpoTable[gRfalDpoTableEntry];
  207. }
  208. /*******************************************************************************/
  209. void rfalDpoSetEnabled( bool enable )
  210. {
  211. gRfalDpoIsEnabled = enable;
  212. }
  213. /*******************************************************************************/
  214. bool rfalDpoIsEnabled( void )
  215. {
  216. return gRfalDpoIsEnabled;
  217. }
  218. #endif /* RFAL_FEATURE_DPO */