st25r3916_com.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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: ST25R3916 firmware
  23. * Revision:
  24. * LANGUAGE: ISO C99
  25. */
  26. /*! \file
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief Implementation of ST25R3916 communication
  31. *
  32. */
  33. /*
  34. ******************************************************************************
  35. * INCLUDES
  36. ******************************************************************************
  37. */
  38. #include "st25r3916.h"
  39. #include "st25r3916_com.h"
  40. #include "st25r3916_led.h"
  41. #include "st_errno.h"
  42. #include "platform.h"
  43. #include "utils.h"
  44. /*
  45. ******************************************************************************
  46. * LOCAL DEFINES
  47. ******************************************************************************
  48. */
  49. #define ST25R3916_OPTIMIZE \
  50. true /*!< Optimization switch: false always write value to register */
  51. #define ST25R3916_I2C_ADDR \
  52. (0xA0U >> 1) /*!< ST25R3916's default I2C address */
  53. #define ST25R3916_REG_LEN 1U /*!< Byte length of a ST25R3916 register */
  54. #define ST25R3916_WRITE_MODE \
  55. (0U << 6) /*!< ST25R3916 Operation Mode: Write */
  56. #define ST25R3916_READ_MODE \
  57. (1U << 6) /*!< ST25R3916 Operation Mode: Read */
  58. #define ST25R3916_CMD_MODE \
  59. (3U << 6) /*!< ST25R3916 Operation Mode: Direct Command */
  60. #define ST25R3916_FIFO_LOAD \
  61. (0x80U) /*!< ST25R3916 Operation Mode: FIFO Load */
  62. #define ST25R3916_FIFO_READ \
  63. (0x9FU) /*!< ST25R3916 Operation Mode: FIFO Read */
  64. #define ST25R3916_PT_A_CONFIG_LOAD \
  65. (0xA0U) /*!< ST25R3916 Operation Mode: Passive Target Memory A-Config Load */
  66. #define ST25R3916_PT_F_CONFIG_LOAD \
  67. (0xA8U) /*!< ST25R3916 Operation Mode: Passive Target Memory F-Config Load */
  68. #define ST25R3916_PT_TSN_DATA_LOAD \
  69. (0xACU) /*!< ST25R3916 Operation Mode: Passive Target Memory TSN Load */
  70. #define ST25R3916_PT_MEM_READ \
  71. (0xBFU) /*!< ST25R3916 Operation Mode: Passive Target Memory Read */
  72. #define ST25R3916_CMD_LEN \
  73. (1U) /*!< ST25R3916 CMD length */
  74. #define ST25R3916_BUF_LEN \
  75. (ST25R3916_CMD_LEN + \
  76. ST25R3916_FIFO_DEPTH) /*!< ST25R3916 communication buffer: CMD + FIFO length */
  77. /*
  78. ******************************************************************************
  79. * MACROS
  80. ******************************************************************************
  81. */
  82. #ifdef RFAL_USE_I2C
  83. #define st25r3916I2CStart() \
  84. platformI2CStart() /*!< ST25R3916 HAL I2C driver macro to start a I2C transfer */
  85. #define st25r3916I2CStop() \
  86. platformI2CStop() /*!< ST25R3916 HAL I2C driver macro to stop a I2C transfer */
  87. #define st25r3916I2CRepeatStart() \
  88. platformI2CRepeatStart() /*!< ST25R3916 HAL I2C driver macro to repeat Start */
  89. #define st25r3916I2CSlaveAddrWR(sA) \
  90. platformI2CSlaveAddrWR( \
  91. sA) /*!< ST25R3916 HAL I2C driver macro to repeat Start */
  92. #define st25r3916I2CSlaveAddrRD(sA) \
  93. platformI2CSlaveAddrRD( \
  94. sA) /*!< ST25R3916 HAL I2C driver macro to repeat Start */
  95. #endif /* RFAL_USE_I2C */
  96. #if defined(ST25R_COM_SINGLETXRX) && !defined(RFAL_USE_I2C)
  97. static uint8_t
  98. comBuf[ST25R3916_BUF_LEN]; /*!< ST25R3916 communication buffer */
  99. static uint16_t comBufIt; /*!< ST25R3916 communication buffer iterator */
  100. #endif /* ST25R_COM_SINGLETXRX */
  101. /*
  102. ******************************************************************************
  103. * LOCAL FUNCTION PROTOTYPES
  104. ******************************************************************************
  105. */
  106. /*!
  107. ******************************************************************************
  108. * \brief ST25R3916 communication Start
  109. *
  110. * This method performs the required actions to start communications with
  111. * ST25R3916, either by SPI or I2C
  112. ******************************************************************************
  113. */
  114. static void st25r3916comStart(void);
  115. /*!
  116. ******************************************************************************
  117. * \brief ST25R3916 communication Stop
  118. *
  119. * This method performs the required actions to terminate communications with
  120. * ST25R3916, either by SPI or I2C
  121. ******************************************************************************
  122. */
  123. static void st25r3916comStop(void);
  124. /*!
  125. ******************************************************************************
  126. * \brief ST25R3916 communication Repeat Start
  127. *
  128. * This method performs the required actions to repeat start a transmission
  129. * with ST25R3916, either by SPI or I2C
  130. ******************************************************************************
  131. */
  132. #ifdef RFAL_USE_I2C
  133. static void st25r3916comRepeatStart(void);
  134. #else
  135. #define st25r3916comRepeatStart()
  136. #endif /* RFAL_USE_I2C */
  137. /*!
  138. ******************************************************************************
  139. * \brief ST25R3916 communication Tx
  140. *
  141. * This method performs the required actions to transmit the given buffer
  142. * to ST25R3916, either by SPI or I2C
  143. *
  144. * \param[in] txBuf : the buffer to transmit
  145. * \param[in] txLen : the length of the buffer to transmit
  146. * \param[in] last : true if last data to be transmitted
  147. * \param[in] txOnly : true no reception is to be performed
  148. *
  149. ******************************************************************************
  150. */
  151. static void st25r3916comTx(const uint8_t* txBuf, uint16_t txLen, bool last, bool txOnly);
  152. /*!
  153. ******************************************************************************
  154. * \brief ST25R3916 communication Rx
  155. *
  156. * This method performs the required actions to receive from ST25R3916 the given
  157. * amount of bytes, either by SPI or I2C
  158. *
  159. * \param[out] rxBuf : the buffer place the received bytes
  160. * \param[in] rxLen : the length to receive
  161. *
  162. ******************************************************************************
  163. */
  164. static void st25r3916comRx(uint8_t* rxBuf, uint16_t rxLen);
  165. /*!
  166. ******************************************************************************
  167. * \brief ST25R3916 communication Tx Byte
  168. *
  169. * This helper method transmits a byte passed by value and not by reference
  170. *
  171. * \param[in] txByte : the value of the byte to be transmitted
  172. * \param[in] last : true if last byte to be transmitted
  173. * \param[in] txOnly : true no reception is to be performed
  174. *
  175. ******************************************************************************
  176. */
  177. static void st25r3916comTxByte(uint8_t txByte, bool last, bool txOnly);
  178. /*
  179. ******************************************************************************
  180. * LOCAL FUNCTION
  181. ******************************************************************************
  182. */
  183. static void st25r3916comStart(void) {
  184. /* Make this operation atomic, disabling ST25R3916 interrupt during communications*/
  185. platformProtectST25RComm();
  186. #ifdef RFAL_USE_I2C
  187. /* I2C Start and send Slave Address */
  188. st25r3916I2CStart();
  189. st25r3916I2CSlaveAddrWR(ST25R3916_I2C_ADDR);
  190. #else
  191. /* Perform the chip select */
  192. platformSpiSelect();
  193. #if defined(ST25R_COM_SINGLETXRX)
  194. comBufIt = 0; /* reset local buffer position */
  195. #endif /* ST25R_COM_SINGLETXRX */
  196. #endif /* RFAL_USE_I2C */
  197. }
  198. /*******************************************************************************/
  199. static void st25r3916comStop(void) {
  200. #ifdef RFAL_USE_I2C
  201. /* Generate Stop signal */
  202. st25r3916I2CStop();
  203. #else
  204. /* Release the chip select */
  205. platformSpiDeselect();
  206. #endif /* RFAL_USE_I2C */
  207. /* reEnable the ST25R3916 interrupt */
  208. platformUnprotectST25RComm();
  209. }
  210. /*******************************************************************************/
  211. #ifdef RFAL_USE_I2C
  212. static void st25r3916comRepeatStart(void) {
  213. st25r3916I2CRepeatStart();
  214. st25r3916I2CSlaveAddrRD(ST25R3916_I2C_ADDR);
  215. }
  216. #endif /* RFAL_USE_I2C */
  217. /*******************************************************************************/
  218. static void st25r3916comTx(const uint8_t* txBuf, uint16_t txLen, bool last, bool txOnly) {
  219. NO_WARNING(last);
  220. NO_WARNING(txOnly);
  221. if(txLen > 0U) {
  222. #ifdef RFAL_USE_I2C
  223. platformI2CTx(txBuf, txLen, last, txOnly);
  224. #else /* RFAL_USE_I2C */
  225. #ifdef ST25R_COM_SINGLETXRX
  226. ST_MEMCPY(
  227. &comBuf[comBufIt],
  228. txBuf,
  229. MIN(txLen,
  230. (ST25R3916_BUF_LEN -
  231. comBufIt))); /* copy tx data to local buffer */
  232. comBufIt +=
  233. MIN(txLen,
  234. (ST25R3916_BUF_LEN -
  235. comBufIt)); /* store position on local buffer */
  236. if(last && txOnly) /* only perform SPI transaction if no Rx will follow */
  237. {
  238. platformSpiTxRx(comBuf, NULL, comBufIt);
  239. }
  240. #else
  241. platformSpiTxRx(txBuf, NULL, txLen);
  242. #endif /* ST25R_COM_SINGLETXRX */
  243. #endif /* RFAL_USE_I2C */
  244. }
  245. }
  246. /*******************************************************************************/
  247. static void st25r3916comRx(uint8_t* rxBuf, uint16_t rxLen) {
  248. if(rxLen > 0U) {
  249. #ifdef RFAL_USE_I2C
  250. platformI2CRx(rxBuf, rxLen);
  251. #else /* RFAL_USE_I2C */
  252. #ifdef ST25R_COM_SINGLETXRX
  253. ST_MEMSET(
  254. &comBuf[comBufIt],
  255. 0x00,
  256. MIN(rxLen,
  257. (ST25R3916_BUF_LEN -
  258. comBufIt))); /* clear outgoing buffer */
  259. platformSpiTxRx(
  260. comBuf,
  261. comBuf,
  262. MIN((comBufIt + rxLen),
  263. ST25R3916_BUF_LEN)); /* transceive as a single SPI call */
  264. ST_MEMCPY(
  265. rxBuf,
  266. &comBuf[comBufIt],
  267. MIN(rxLen,
  268. (ST25R3916_BUF_LEN -
  269. comBufIt))); /* copy from local buf to output buffer and skip cmd byte */
  270. #else
  271. if(rxBuf != NULL) {
  272. ST_MEMSET(
  273. rxBuf, 0x00, rxLen); /* clear outgoing buffer */
  274. }
  275. platformSpiTxRx(NULL, rxBuf, rxLen);
  276. #endif /* ST25R_COM_SINGLETXRX */
  277. #endif /* RFAL_USE_I2C */
  278. }
  279. }
  280. /*******************************************************************************/
  281. static void st25r3916comTxByte(uint8_t txByte, bool last, bool txOnly) {
  282. uint8_t val = txByte; /* MISRA 17.8: use intermediate variable */
  283. st25r3916comTx(&val, ST25R3916_REG_LEN, last, txOnly);
  284. }
  285. /*
  286. ******************************************************************************
  287. * GLOBAL FUNCTIONS
  288. ******************************************************************************
  289. */
  290. /*******************************************************************************/
  291. ReturnCode st25r3916ReadRegister(uint8_t reg, uint8_t* val) {
  292. return st25r3916ReadMultipleRegisters(reg, val, ST25R3916_REG_LEN);
  293. }
  294. /*******************************************************************************/
  295. ReturnCode st25r3916ReadMultipleRegisters(uint8_t reg, uint8_t* values, uint8_t length) {
  296. if(length > 0U) {
  297. st25r3916comStart();
  298. /* If is a space-B register send a direct command first */
  299. if((reg & ST25R3916_SPACE_B) != 0U) {
  300. st25r3916comTxByte(ST25R3916_CMD_SPACE_B_ACCESS, false, false);
  301. }
  302. st25r3916comTxByte(((reg & ~ST25R3916_SPACE_B) | ST25R3916_READ_MODE), true, false);
  303. st25r3916comRepeatStart();
  304. st25r3916comRx(values, length);
  305. st25r3916comStop();
  306. }
  307. return ERR_NONE;
  308. }
  309. /*******************************************************************************/
  310. ReturnCode st25r3916WriteRegister(uint8_t reg, uint8_t val) {
  311. uint8_t value = val; /* MISRA 17.8: use intermediate variable */
  312. return st25r3916WriteMultipleRegisters(reg, &value, ST25R3916_REG_LEN);
  313. }
  314. /*******************************************************************************/
  315. ReturnCode st25r3916WriteMultipleRegisters(uint8_t reg, const uint8_t* values, uint8_t length) {
  316. if(length > 0U) {
  317. st25r3916comStart();
  318. if((reg & ST25R3916_SPACE_B) != 0U) {
  319. st25r3916comTxByte(ST25R3916_CMD_SPACE_B_ACCESS, false, true);
  320. }
  321. st25r3916comTxByte(((reg & ~ST25R3916_SPACE_B) | ST25R3916_WRITE_MODE), false, true);
  322. st25r3916comTx(values, length, true, true);
  323. st25r3916comStop();
  324. /* Send a WriteMultiReg event to LED handling */
  325. st25r3916ledEvtWrMultiReg(reg, values, length);
  326. }
  327. return ERR_NONE;
  328. }
  329. /*******************************************************************************/
  330. ReturnCode st25r3916WriteFifo(const uint8_t* values, uint16_t length) {
  331. if(length > ST25R3916_FIFO_DEPTH) {
  332. return ERR_PARAM;
  333. }
  334. if(length > 0U) {
  335. st25r3916comStart();
  336. st25r3916comTxByte(ST25R3916_FIFO_LOAD, false, true);
  337. st25r3916comTx(values, length, true, true);
  338. st25r3916comStop();
  339. }
  340. return ERR_NONE;
  341. }
  342. /*******************************************************************************/
  343. ReturnCode st25r3916ReadFifo(uint8_t* buf, uint16_t length) {
  344. if(length > 0U) {
  345. st25r3916comStart();
  346. st25r3916comTxByte(ST25R3916_FIFO_READ, true, false);
  347. st25r3916comRepeatStart();
  348. st25r3916comRx(buf, length);
  349. st25r3916comStop();
  350. }
  351. return ERR_NONE;
  352. }
  353. /*******************************************************************************/
  354. ReturnCode st25r3916WritePTMem(const uint8_t* values, uint16_t length) {
  355. if(length > ST25R3916_PTM_LEN) {
  356. return ERR_PARAM;
  357. }
  358. if(length > 0U) {
  359. st25r3916comStart();
  360. st25r3916comTxByte(ST25R3916_PT_A_CONFIG_LOAD, false, true);
  361. st25r3916comTx(values, length, true, true);
  362. st25r3916comStop();
  363. }
  364. return ERR_NONE;
  365. }
  366. /*******************************************************************************/
  367. ReturnCode st25r3916ReadPTMem(uint8_t* values, uint16_t length) {
  368. uint8_t
  369. tmp[ST25R3916_REG_LEN +
  370. ST25R3916_PTM_LEN]; /* local buffer to handle prepended byte on I2C and SPI */
  371. if(length > 0U) {
  372. if(length > ST25R3916_PTM_LEN) {
  373. return ERR_PARAM;
  374. }
  375. st25r3916comStart();
  376. st25r3916comTxByte(ST25R3916_PT_MEM_READ, true, false);
  377. st25r3916comRepeatStart();
  378. st25r3916comRx(tmp, (ST25R3916_REG_LEN + length)); /* skip prepended byte */
  379. st25r3916comStop();
  380. /* Copy PTMem content without prepended byte */
  381. ST_MEMCPY(values, (tmp + ST25R3916_REG_LEN), length);
  382. }
  383. return ERR_NONE;
  384. }
  385. /*******************************************************************************/
  386. ReturnCode st25r3916WritePTMemF(const uint8_t* values, uint16_t length) {
  387. if(length > (ST25R3916_PTM_F_LEN + ST25R3916_PTM_TSN_LEN)) {
  388. return ERR_PARAM;
  389. }
  390. if(length > 0U) {
  391. st25r3916comStart();
  392. st25r3916comTxByte(ST25R3916_PT_F_CONFIG_LOAD, false, true);
  393. st25r3916comTx(values, length, true, true);
  394. st25r3916comStop();
  395. }
  396. return ERR_NONE;
  397. }
  398. /*******************************************************************************/
  399. ReturnCode st25r3916WritePTMemTSN(const uint8_t* values, uint16_t length) {
  400. if(length > ST25R3916_PTM_TSN_LEN) {
  401. return ERR_PARAM;
  402. }
  403. if(length > 0U) {
  404. st25r3916comStart();
  405. st25r3916comTxByte(ST25R3916_PT_TSN_DATA_LOAD, false, true);
  406. st25r3916comTx(values, length, true, true);
  407. st25r3916comStop();
  408. }
  409. return ERR_NONE;
  410. }
  411. /*******************************************************************************/
  412. ReturnCode st25r3916ExecuteCommand(uint8_t cmd) {
  413. st25r3916comStart();
  414. st25r3916comTxByte((cmd | ST25R3916_CMD_MODE), true, true);
  415. st25r3916comStop();
  416. /* Send a cmd event to LED handling */
  417. st25r3916ledEvtCmd(cmd);
  418. return ERR_NONE;
  419. }
  420. /*******************************************************************************/
  421. ReturnCode st25r3916ReadTestRegister(uint8_t reg, uint8_t* val) {
  422. st25r3916comStart();
  423. st25r3916comTxByte(ST25R3916_CMD_TEST_ACCESS, false, false);
  424. st25r3916comTxByte((reg | ST25R3916_READ_MODE), true, false);
  425. st25r3916comRepeatStart();
  426. st25r3916comRx(val, ST25R3916_REG_LEN);
  427. st25r3916comStop();
  428. return ERR_NONE;
  429. }
  430. /*******************************************************************************/
  431. ReturnCode st25r3916WriteTestRegister(uint8_t reg, uint8_t val) {
  432. uint8_t value = val; /* MISRA 17.8: use intermediate variable */
  433. st25r3916comStart();
  434. st25r3916comTxByte(ST25R3916_CMD_TEST_ACCESS, false, true);
  435. st25r3916comTxByte((reg | ST25R3916_WRITE_MODE), false, true);
  436. st25r3916comTx(&value, ST25R3916_REG_LEN, true, true);
  437. st25r3916comStop();
  438. return ERR_NONE;
  439. }
  440. /*******************************************************************************/
  441. ReturnCode st25r3916ClrRegisterBits(uint8_t reg, uint8_t clr_mask) {
  442. ReturnCode ret;
  443. uint8_t rdVal;
  444. /* Read current reg value */
  445. EXIT_ON_ERR(ret, st25r3916ReadRegister(reg, &rdVal));
  446. /* Only perform a Write if value to be written is different */
  447. if(ST25R3916_OPTIMIZE && (rdVal == (uint8_t)(rdVal & ~clr_mask))) {
  448. return ERR_NONE;
  449. }
  450. /* Write new reg value */
  451. return st25r3916WriteRegister(reg, (uint8_t)(rdVal & ~clr_mask));
  452. }
  453. /*******************************************************************************/
  454. ReturnCode st25r3916SetRegisterBits(uint8_t reg, uint8_t set_mask) {
  455. ReturnCode ret;
  456. uint8_t rdVal;
  457. /* Read current reg value */
  458. EXIT_ON_ERR(ret, st25r3916ReadRegister(reg, &rdVal));
  459. /* Only perform a Write if the value to be written is different */
  460. if(ST25R3916_OPTIMIZE && (rdVal == (rdVal | set_mask))) {
  461. return ERR_NONE;
  462. }
  463. /* Write new reg value */
  464. return st25r3916WriteRegister(reg, (rdVal | set_mask));
  465. }
  466. /*******************************************************************************/
  467. ReturnCode st25r3916ChangeRegisterBits(uint8_t reg, uint8_t valueMask, uint8_t value) {
  468. return st25r3916ModifyRegister(reg, valueMask, (valueMask & value));
  469. }
  470. /*******************************************************************************/
  471. ReturnCode st25r3916ModifyRegister(uint8_t reg, uint8_t clr_mask, uint8_t set_mask) {
  472. ReturnCode ret;
  473. uint8_t rdVal;
  474. uint8_t wrVal;
  475. /* Read current reg value */
  476. EXIT_ON_ERR(ret, st25r3916ReadRegister(reg, &rdVal));
  477. /* Compute new value */
  478. wrVal = (uint8_t)(rdVal & ~clr_mask);
  479. wrVal |= set_mask;
  480. /* Only perform a Write if the value to be written is different */
  481. if(ST25R3916_OPTIMIZE && (rdVal == wrVal)) {
  482. return ERR_NONE;
  483. }
  484. /* Write new reg value */
  485. return st25r3916WriteRegister(reg, wrVal);
  486. }
  487. /*******************************************************************************/
  488. ReturnCode st25r3916ChangeTestRegisterBits(uint8_t reg, uint8_t valueMask, uint8_t value) {
  489. ReturnCode ret;
  490. uint8_t rdVal;
  491. uint8_t wrVal;
  492. /* Read current reg value */
  493. EXIT_ON_ERR(ret, st25r3916ReadTestRegister(reg, &rdVal));
  494. /* Compute new value */
  495. wrVal = (uint8_t)(rdVal & ~valueMask);
  496. wrVal |= (uint8_t)(value & valueMask);
  497. /* Only perform a Write if the value to be written is different */
  498. if(ST25R3916_OPTIMIZE && (rdVal == wrVal)) {
  499. return ERR_NONE;
  500. }
  501. /* Write new reg value */
  502. return st25r3916WriteTestRegister(reg, wrVal);
  503. }
  504. /*******************************************************************************/
  505. bool st25r3916CheckReg(uint8_t reg, uint8_t mask, uint8_t val) {
  506. uint8_t regVal;
  507. regVal = 0;
  508. st25r3916ReadRegister(reg, &regVal);
  509. return ((regVal & mask) == val);
  510. }
  511. /*******************************************************************************/
  512. bool st25r3916IsRegValid(uint8_t reg) {
  513. #pragma GCC diagnostic ignored "-Wtype-limits"
  514. if(!(((int16_t)reg >= (int32_t)ST25R3916_REG_IO_CONF1) &&
  515. (reg <= (ST25R3916_SPACE_B | ST25R3916_REG_IC_IDENTITY)))) {
  516. return false;
  517. }
  518. return true;
  519. }