rfal_analogConfig.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. * 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_analogConfig.c
  27. *
  28. * \author bkam
  29. *
  30. * \brief Funcitons to manage and set analog settings.
  31. *
  32. */
  33. /*
  34. ******************************************************************************
  35. * INCLUDES
  36. ******************************************************************************
  37. */
  38. #include "rfal_analogConfig.h"
  39. #include "rfal_chip.h"
  40. #include "st_errno.h"
  41. #include "platform.h"
  42. #include "utils.h"
  43. /* Check whether the Default Analog settings are to be used or custom ones */
  44. #ifdef RFAL_ANALOG_CONFIG_CUSTOM
  45. extern const uint8_t* rfalAnalogConfigCustomSettings;
  46. extern const uint16_t rfalAnalogConfigCustomSettingsLength;
  47. #else
  48. #include "rfal_analogConfigTbl.h"
  49. #endif
  50. /*
  51. ******************************************************************************
  52. * DEFINES
  53. ******************************************************************************
  54. */
  55. #define RFAL_TEST_REG 0x0080U /*!< Test Register indicator */
  56. /*
  57. ******************************************************************************
  58. * MACROS
  59. ******************************************************************************
  60. */
  61. /*
  62. ******************************************************************************
  63. * LOCAL DATA TYPES
  64. ******************************************************************************
  65. */
  66. #if RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG
  67. static uint8_t
  68. gRfalAnalogConfig[RFAL_ANALOG_CONFIG_TBL_SIZE]; /*!< Analog Configuration Settings List */
  69. #endif /* RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG */
  70. /*! Struct for Analog Config Look Up Table Update */
  71. typedef struct {
  72. const uint8_t*
  73. currentAnalogConfigTbl; /*!< Reference to start of current Analog Configuration */
  74. uint16_t configTblSize; /*!< Total size of Analog Configuration */
  75. bool ready; /*!< Indicate if Look Up Table is complete and ready for use */
  76. } rfalAnalogConfigMgmt;
  77. static rfalAnalogConfigMgmt gRfalAnalogConfigMgmt; /*!< Analog Configuration LUT management */
  78. /*
  79. ******************************************************************************
  80. * LOCAL TABLES
  81. ******************************************************************************
  82. */
  83. /*
  84. ******************************************************************************
  85. * LOCAL FUNCTION PROTOTYPES
  86. ******************************************************************************
  87. */
  88. static rfalAnalogConfigNum
  89. rfalAnalogConfigSearch(rfalAnalogConfigId configId, uint16_t* configOffset);
  90. #if RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG
  91. static void rfalAnalogConfigPtrUpdate(const uint8_t* analogConfigTbl);
  92. #endif /* RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG */
  93. /*
  94. ******************************************************************************
  95. * GLOBAL VARIABLE DEFINITIONS
  96. ******************************************************************************
  97. */
  98. /*
  99. ******************************************************************************
  100. * GLOBAL FUNCTIONS
  101. ******************************************************************************
  102. */
  103. void rfalAnalogConfigInitialize(void) {
  104. /* Use default Analog configuration settings in Flash by default. */
  105. /* Check whether the Default Analog settings are to be used or custom ones */
  106. #ifdef RFAL_ANALOG_CONFIG_CUSTOM
  107. gRfalAnalogConfigMgmt.currentAnalogConfigTbl = (const uint8_t*)&rfalAnalogConfigCustomSettings;
  108. gRfalAnalogConfigMgmt.configTblSize = rfalAnalogConfigCustomSettingsLength;
  109. #else
  110. gRfalAnalogConfigMgmt.currentAnalogConfigTbl =
  111. (const uint8_t*)&rfalAnalogConfigDefaultSettings;
  112. gRfalAnalogConfigMgmt.configTblSize = sizeof(rfalAnalogConfigDefaultSettings);
  113. #endif
  114. gRfalAnalogConfigMgmt.ready = true;
  115. } /* rfalAnalogConfigInitialize() */
  116. bool rfalAnalogConfigIsReady(void) {
  117. return gRfalAnalogConfigMgmt.ready;
  118. }
  119. ReturnCode rfalAnalogConfigListWriteRaw(const uint8_t* configTbl, uint16_t configTblSize) {
  120. #if RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG
  121. /* Check if the Configuration Table exceed the Table size */
  122. if(configTblSize >= RFAL_ANALOG_CONFIG_TBL_SIZE) {
  123. rfalAnalogConfigInitialize(); /* Revert to default Analog Configuration */
  124. return ERR_NOMEM;
  125. }
  126. /* Check for invalid parameters */
  127. if((configTbl == NULL) || (configTblSize == 0U)) {
  128. return ERR_PARAM;
  129. }
  130. /* NOTE: Function does not check for the validity of the Table contents (conf IDs, conf sets, register address) */
  131. ST_MEMCPY(gRfalAnalogConfig, configTbl, configTblSize);
  132. /* Update the total size of configuration settings */
  133. gRfalAnalogConfigMgmt.configTblSize = configTblSize;
  134. rfalAnalogConfigPtrUpdate(gRfalAnalogConfig);
  135. return ERR_NONE;
  136. #else
  137. // If Analog Configuration Update is to be disabled
  138. NO_WARNING(configTbl);
  139. NO_WARNING(configTblSize);
  140. return ERR_REQUEST;
  141. #endif /* RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG */
  142. }
  143. ReturnCode rfalAnalogConfigListWrite(uint8_t more, const rfalAnalogConfig* config) {
  144. #if RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG
  145. rfalAnalogConfigId configId;
  146. rfalAnalogConfigNum numConfig;
  147. uint8_t configSize;
  148. if(true == gRfalAnalogConfigMgmt.ready) { /* First Update to the Configuration list. */
  149. gRfalAnalogConfigMgmt.ready = false; // invalidate the config List
  150. gRfalAnalogConfigMgmt.configTblSize = 0; // Clear the config List
  151. }
  152. configId = GETU16(config->id);
  153. /* Check validity of the Configuration ID. */
  154. if((RFAL_ANALOG_CONFIG_TECH_RFU <= RFAL_ANALOG_CONFIG_ID_GET_TECH(configId)) ||
  155. ((RFAL_ANALOG_CONFIG_BITRATE_6780 < RFAL_ANALOG_CONFIG_ID_GET_BITRATE(configId)) &&
  156. (RFAL_ANALOG_CONFIG_BITRATE_1OF4 > RFAL_ANALOG_CONFIG_ID_GET_BITRATE(configId))) ||
  157. (RFAL_ANALOG_CONFIG_BITRATE_1OF256 < RFAL_ANALOG_CONFIG_ID_GET_BITRATE(configId))) {
  158. rfalAnalogConfigInitialize(); /* Revert to default Analog Configuration */
  159. return ERR_PARAM;
  160. }
  161. numConfig = config->num;
  162. configSize =
  163. (uint8_t)(sizeof(rfalAnalogConfigId) + sizeof(rfalAnalogConfigNum) + (numConfig * sizeof(rfalAnalogConfigRegAddrMaskVal)));
  164. /* Check if the Configuration Set exceed the Table size. */
  165. if(RFAL_ANALOG_CONFIG_TBL_SIZE <= (gRfalAnalogConfigMgmt.configTblSize + configSize)) {
  166. rfalAnalogConfigInitialize(); /* Revert to default Analog Configuration */
  167. return ERR_NOMEM;
  168. }
  169. /* NOTE: Function does not check for the validity of the Register Address. */
  170. ST_MEMCPY(
  171. &gRfalAnalogConfig[gRfalAnalogConfigMgmt.configTblSize],
  172. (const uint8_t*)config,
  173. configSize);
  174. /* Increment the total size of configuration settings. */
  175. gRfalAnalogConfigMgmt.configTblSize += configSize;
  176. /* Check if it is the last Analog Configuration to load. */
  177. if(RFAL_ANALOG_CONFIG_UPDATE_LAST ==
  178. more) { /* Update the Analog Configuration to the new settings. */
  179. rfalAnalogConfigPtrUpdate(gRfalAnalogConfig);
  180. }
  181. return ERR_NONE;
  182. #else
  183. // If Analog Configuration Update is to be disabled
  184. NO_WARNING(config);
  185. NO_WARNING(more);
  186. return ERR_DISABLED;
  187. #endif /* RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG */
  188. } /* rfalAnalogConfigListUpdate() */
  189. ReturnCode
  190. rfalAnalogConfigListReadRaw(uint8_t* tblBuf, uint16_t tblBufLen, uint16_t* configTblSize) {
  191. /* Check if the the current table will fit into the given buffer */
  192. if(tblBufLen < gRfalAnalogConfigMgmt.configTblSize) {
  193. return ERR_NOMEM;
  194. }
  195. /* Check for invalid parameters */
  196. if(configTblSize == NULL) {
  197. return ERR_PARAM;
  198. }
  199. /* Copy the whole Table to the given buffer */
  200. if(gRfalAnalogConfigMgmt.configTblSize > 0U) /* MISRA 21.18 */
  201. {
  202. ST_MEMCPY(
  203. tblBuf,
  204. gRfalAnalogConfigMgmt.currentAnalogConfigTbl,
  205. gRfalAnalogConfigMgmt.configTblSize);
  206. }
  207. *configTblSize = gRfalAnalogConfigMgmt.configTblSize;
  208. return ERR_NONE;
  209. }
  210. ReturnCode rfalAnalogConfigListRead(
  211. rfalAnalogConfigOffset* configOffset,
  212. uint8_t* more,
  213. rfalAnalogConfig* config,
  214. rfalAnalogConfigNum numConfig) {
  215. uint16_t configSize;
  216. rfalAnalogConfigOffset offset = *configOffset;
  217. rfalAnalogConfigNum numConfigSet;
  218. /* Check if the number of register-mask-value settings for the respective Configuration ID will fit into the buffer passed in. */
  219. if(gRfalAnalogConfigMgmt.currentAnalogConfigTbl[offset + sizeof(rfalAnalogConfigId)] >
  220. numConfig) {
  221. return ERR_NOMEM;
  222. }
  223. /* Get the number of Configuration set */
  224. numConfigSet =
  225. gRfalAnalogConfigMgmt.currentAnalogConfigTbl[offset + sizeof(rfalAnalogConfigId)];
  226. /* Pass Configuration Register-Mask-Value sets */
  227. configSize =
  228. (sizeof(rfalAnalogConfigId) + sizeof(rfalAnalogConfigNum) +
  229. (uint16_t)(numConfigSet * sizeof(rfalAnalogConfigRegAddrMaskVal)));
  230. ST_MEMCPY((uint8_t*)config, &gRfalAnalogConfigMgmt.currentAnalogConfigTbl[offset], configSize);
  231. *configOffset = offset + configSize;
  232. /* Check if it is the last Analog Configuration in the Table.*/
  233. *more =
  234. (uint8_t)((*configOffset >= gRfalAnalogConfigMgmt.configTblSize) ? RFAL_ANALOG_CONFIG_UPDATE_LAST : RFAL_ANALOG_CONFIG_UPDATE_MORE);
  235. return ERR_NONE;
  236. } /* rfalAnalogConfigListRead() */
  237. ReturnCode rfalSetAnalogConfig(rfalAnalogConfigId configId) {
  238. rfalAnalogConfigOffset configOffset = 0;
  239. rfalAnalogConfigNum numConfigSet;
  240. const rfalAnalogConfigRegAddrMaskVal* configTbl;
  241. ReturnCode retCode = ERR_NONE;
  242. rfalAnalogConfigNum i;
  243. if(true != gRfalAnalogConfigMgmt.ready) {
  244. return ERR_REQUEST;
  245. }
  246. /* Search LUT for the specific Configuration ID. */
  247. while(true) {
  248. numConfigSet = rfalAnalogConfigSearch(configId, &configOffset);
  249. if(RFAL_ANALOG_CONFIG_LUT_NOT_FOUND == numConfigSet) {
  250. break;
  251. }
  252. configTbl =
  253. (rfalAnalogConfigRegAddrMaskVal*)((uint32_t)gRfalAnalogConfigMgmt.currentAnalogConfigTbl + (uint32_t)configOffset);
  254. /* Increment the offset to the next index to search from. */
  255. configOffset += (uint16_t)(numConfigSet * sizeof(rfalAnalogConfigRegAddrMaskVal));
  256. if((gRfalAnalogConfigMgmt.configTblSize + 1U) <
  257. configOffset) { /* Error check make sure that the we do not access outside the configuration Table Size */
  258. return ERR_NOMEM;
  259. }
  260. for(i = 0; i < numConfigSet; i++) {
  261. if((GETU16(configTbl[i].addr) & RFAL_TEST_REG) != 0U) {
  262. EXIT_ON_ERR(
  263. retCode,
  264. rfalChipChangeTestRegBits(
  265. (GETU16(configTbl[i].addr) & ~RFAL_TEST_REG),
  266. configTbl[i].mask,
  267. configTbl[i].val));
  268. } else {
  269. EXIT_ON_ERR(
  270. retCode,
  271. rfalChipChangeRegBits(
  272. GETU16(configTbl[i].addr), configTbl[i].mask, configTbl[i].val));
  273. }
  274. }
  275. } /* while(found Analog Config Id) */
  276. return retCode;
  277. } /* rfalSetAnalogConfig() */
  278. uint16_t rfalAnalogConfigGenModeID(rfalMode md, rfalBitRate br, uint16_t dir) {
  279. uint16_t id;
  280. /* Assign Poll/Listen Mode */
  281. id = ((md >= RFAL_MODE_LISTEN_NFCA) ? RFAL_ANALOG_CONFIG_LISTEN : RFAL_ANALOG_CONFIG_POLL);
  282. /* Assign Technology */
  283. switch(md) {
  284. case RFAL_MODE_POLL_NFCA:
  285. case RFAL_MODE_POLL_NFCA_T1T:
  286. case RFAL_MODE_LISTEN_NFCA:
  287. id |= RFAL_ANALOG_CONFIG_TECH_NFCA;
  288. break;
  289. case RFAL_MODE_POLL_NFCB:
  290. case RFAL_MODE_POLL_B_PRIME:
  291. case RFAL_MODE_POLL_B_CTS:
  292. case RFAL_MODE_LISTEN_NFCB:
  293. id |= RFAL_ANALOG_CONFIG_TECH_NFCB;
  294. break;
  295. case RFAL_MODE_POLL_NFCF:
  296. case RFAL_MODE_LISTEN_NFCF:
  297. id |= RFAL_ANALOG_CONFIG_TECH_NFCF;
  298. break;
  299. case RFAL_MODE_POLL_NFCV:
  300. case RFAL_MODE_POLL_PICOPASS:
  301. id |= RFAL_ANALOG_CONFIG_TECH_NFCV;
  302. break;
  303. case RFAL_MODE_POLL_ACTIVE_P2P:
  304. case RFAL_MODE_LISTEN_ACTIVE_P2P:
  305. id |= RFAL_ANALOG_CONFIG_TECH_AP2P;
  306. break;
  307. default:
  308. id = RFAL_ANALOG_CONFIG_TECH_CHIP;
  309. break;
  310. }
  311. /* Assign Bitrate */
  312. id |=
  313. (((((uint16_t)(br) >= (uint16_t)RFAL_BR_52p97) ? (uint16_t)(br) : ((uint16_t)(br) + 1U))
  314. << RFAL_ANALOG_CONFIG_BITRATE_SHIFT) &
  315. RFAL_ANALOG_CONFIG_BITRATE_MASK);
  316. /* Assign Direction */
  317. id |= ((dir << RFAL_ANALOG_CONFIG_DIRECTION_SHIFT) & RFAL_ANALOG_CONFIG_DIRECTION_MASK);
  318. return id;
  319. } /* rfalAnalogConfigGenModeID() */
  320. /*
  321. ******************************************************************************
  322. * LOCAL FUNCTIONS
  323. ******************************************************************************
  324. */
  325. /*!
  326. *****************************************************************************
  327. * \brief Update the link to Analog Configuration LUT
  328. *
  329. * Update the link to the Analog Configuration LUT for the subsequent search
  330. * of Analog Settings.
  331. *
  332. * \param[in] analogConfigTbl: reference to the start of the new Analog Configuration Table
  333. *
  334. *****************************************************************************
  335. */
  336. #if RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG
  337. static void rfalAnalogConfigPtrUpdate(const uint8_t* analogConfigTbl) {
  338. gRfalAnalogConfigMgmt.currentAnalogConfigTbl = analogConfigTbl;
  339. gRfalAnalogConfigMgmt.ready = true;
  340. } /* rfalAnalogConfigPtrUpdate() */
  341. #endif /* RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG */
  342. /*!
  343. *****************************************************************************
  344. * \brief Search the Analog Configuration LUT for a specific Configuration ID.
  345. *
  346. * Search the Analog Configuration LUT for the Configuration ID.
  347. *
  348. * \param[in] configId: Configuration ID to search for.
  349. * \param[in] configOffset: Configuration Offset in Table
  350. *
  351. * \return number of Configuration Sets
  352. * \return #RFAL_ANALOG_CONFIG_LUT_NOT_FOUND in case Configuration ID is not found.
  353. *****************************************************************************
  354. */
  355. static rfalAnalogConfigNum
  356. rfalAnalogConfigSearch(rfalAnalogConfigId configId, uint16_t* configOffset) {
  357. rfalAnalogConfigId foundConfigId;
  358. rfalAnalogConfigId configIdMaskVal;
  359. const uint8_t* configTbl;
  360. const uint8_t* currentConfigTbl;
  361. uint16_t i;
  362. currentConfigTbl = gRfalAnalogConfigMgmt.currentAnalogConfigTbl;
  363. configIdMaskVal =
  364. ((RFAL_ANALOG_CONFIG_POLL_LISTEN_MODE_MASK | RFAL_ANALOG_CONFIG_BITRATE_MASK) |
  365. ((RFAL_ANALOG_CONFIG_TECH_CHIP == RFAL_ANALOG_CONFIG_ID_GET_TECH(configId)) ?
  366. (RFAL_ANALOG_CONFIG_TECH_MASK | RFAL_ANALOG_CONFIG_CHIP_SPECIFIC_MASK) :
  367. configId) |
  368. ((RFAL_ANALOG_CONFIG_NO_DIRECTION == RFAL_ANALOG_CONFIG_ID_GET_DIRECTION(configId)) ?
  369. RFAL_ANALOG_CONFIG_DIRECTION_MASK :
  370. configId));
  371. /* When specific ConfigIDs are to be used, override search mask */
  372. if((RFAL_ANALOG_CONFIG_ID_GET_DIRECTION(configId) == RFAL_ANALOG_CONFIG_DPO)) {
  373. configIdMaskVal =
  374. (RFAL_ANALOG_CONFIG_POLL_LISTEN_MODE_MASK | RFAL_ANALOG_CONFIG_TECH_MASK |
  375. RFAL_ANALOG_CONFIG_BITRATE_MASK | RFAL_ANALOG_CONFIG_DIRECTION_MASK);
  376. }
  377. i = *configOffset;
  378. while(i < gRfalAnalogConfigMgmt.configTblSize) {
  379. configTbl = &currentConfigTbl[i];
  380. foundConfigId = GETU16(configTbl);
  381. if(configId == (foundConfigId & configIdMaskVal)) {
  382. *configOffset =
  383. (uint16_t)(i + sizeof(rfalAnalogConfigId) + sizeof(rfalAnalogConfigNum));
  384. return configTbl[sizeof(rfalAnalogConfigId)];
  385. }
  386. /* If Config Id does not match, increment to next Configuration Id */
  387. i +=
  388. (uint16_t)(sizeof(rfalAnalogConfigId) + sizeof(rfalAnalogConfigNum) + (configTbl[sizeof(rfalAnalogConfigId)] * sizeof(rfalAnalogConfigRegAddrMaskVal)));
  389. } /* for */
  390. return RFAL_ANALOG_CONFIG_LUT_NOT_FOUND;
  391. } /* rfalAnalogConfigSearch() */