rfal_nfcb.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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_nfcb.c
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief Implementation of NFC-B (ISO14443B) helpers
  31. *
  32. */
  33. /*
  34. ******************************************************************************
  35. * INCLUDES
  36. ******************************************************************************
  37. */
  38. #include "rfal_nfcb.h"
  39. #include "utils.h"
  40. /*
  41. ******************************************************************************
  42. * ENABLE SWITCH
  43. ******************************************************************************
  44. */
  45. #ifndef RFAL_FEATURE_NFCB
  46. #define RFAL_FEATURE_NFCB false /* NFC-B module configuration missing. Disabled by default */
  47. #endif
  48. #if RFAL_FEATURE_NFCB
  49. /*
  50. ******************************************************************************
  51. * GLOBAL DEFINES
  52. ******************************************************************************
  53. */
  54. #define RFAL_NFCB_SENSB_REQ_EXT_SENSB_RES_SUPPORTED \
  55. 0x10U /*!< Bit mask for Extended SensB Response support in SENSB_REQ */
  56. #define RFAL_NFCB_SENSB_RES_PROT_TYPE_RFU \
  57. 0x08U /*!< Bit mask for Protocol Type RFU in SENSB_RES */
  58. #define RFAL_NFCB_SLOT_MARKER_SC_SHIFT \
  59. 4U /*!< Slot Code position on SLOT_MARKER APn */
  60. #define RFAL_NFCB_SLOTMARKER_SLOTCODE_MIN \
  61. 1U /*!< SLOT_MARKER Slot Code minimum Digital 1.1 Table 37 */
  62. #define RFAL_NFCB_SLOTMARKER_SLOTCODE_MAX \
  63. 16U /*!< SLOT_MARKER Slot Code maximum Digital 1.1 Table 37 */
  64. #define RFAL_NFCB_ACTIVATION_FWT \
  65. (RFAL_NFCB_FWTSENSB + RFAL_NFCB_DTPOLL_20) /*!< FWT(SENSB) + dTbPoll Digital 2.0 7.9.1.3 */
  66. /*! Advanced and Extended bit mask in Parameter of SENSB_REQ */
  67. #define RFAL_NFCB_SENSB_REQ_PARAM \
  68. (RFAL_NFCB_SENSB_REQ_ADV_FEATURE | RFAL_NFCB_SENSB_REQ_EXT_SENSB_RES_SUPPORTED)
  69. /*! NFC-B commands definition */
  70. enum {
  71. RFAL_NFCB_CMD_SENSB_REQ = 0x05, /*!< SENSB_REQ (REQB) & SLOT_MARKER Digital 1.1 Table 24 */
  72. RFAL_NFCB_CMD_SENSB_RES = 0x50, /*!< SENSB_RES (ATQB) & SLOT_MARKER Digital 1.1 Table 27 */
  73. RFAL_NFCB_CMD_SLPB_REQ = 0x50, /*!< SLPB_REQ (HLTB command) Digital 1.1 Table 38 */
  74. RFAL_NFCB_CMD_SLPB_RES = 0x00 /*!< SLPB_RES (HLTB Answer) Digital 1.1 Table 39 */
  75. };
  76. /*
  77. ******************************************************************************
  78. * GLOBAL MACROS
  79. ******************************************************************************
  80. */
  81. #define rfalNfcbNI2NumberOfSlots(ni) \
  82. (uint8_t)(1U << (ni)) /*!< Converts the Number of slots Identifier to slot number */
  83. /*
  84. ******************************************************************************
  85. * GLOBAL TYPES
  86. ******************************************************************************
  87. */
  88. /*! ALLB_REQ (WUPB) and SENSB_REQ (REQB) Command Format Digital 1.1 7.6.1 */
  89. typedef struct {
  90. uint8_t cmd; /*!< xxxxB_REQ: 05h */
  91. uint8_t AFI; /*!< NFC Identifier */
  92. uint8_t PARAM; /*!< Application Data */
  93. } rfalNfcbSensbReq;
  94. /*! SLOT_MARKER Command format Digital 1.1 7.7.1 */
  95. typedef struct {
  96. uint8_t APn; /*!< Slot number 2..16 | 0101b */
  97. } rfalNfcbSlotMarker;
  98. /*! SLPB_REQ (HLTB) Command Format Digital 1.1 7.8.1 */
  99. typedef struct {
  100. uint8_t cmd; /*!< SLPB_REQ: 50h */
  101. uint8_t nfcid0[RFAL_NFCB_NFCID0_LEN]; /*!< NFC Identifier (PUPI)*/
  102. } rfalNfcbSlpbReq;
  103. /*! SLPB_RES (HLTB) Response Format Digital 1.1 7.8.2 */
  104. typedef struct {
  105. uint8_t cmd; /*!< SLPB_RES: 00h */
  106. } rfalNfcbSlpbRes;
  107. /*! RFAL NFC-B instance */
  108. typedef struct {
  109. uint8_t AFI; /*!< AFI to be used */
  110. uint8_t PARAM; /*!< PARAM to be used */
  111. } rfalNfcb;
  112. /*
  113. ******************************************************************************
  114. * LOCAL FUNCTION PROTOTYPES
  115. ******************************************************************************
  116. */
  117. static ReturnCode rfalNfcbCheckSensbRes(const rfalNfcbSensbRes* sensbRes, uint8_t sensbResLen);
  118. /*
  119. ******************************************************************************
  120. * LOCAL VARIABLES
  121. ******************************************************************************
  122. */
  123. static rfalNfcb gRfalNfcb; /*!< RFAL NFC-B Instance */
  124. /*
  125. ******************************************************************************
  126. * LOCAL FUNCTIONS
  127. ******************************************************************************
  128. */
  129. /*******************************************************************************/
  130. static ReturnCode rfalNfcbCheckSensbRes(const rfalNfcbSensbRes* sensbRes, uint8_t sensbResLen) {
  131. /* Check response length */
  132. if(((sensbResLen != RFAL_NFCB_SENSB_RES_LEN) &&
  133. (sensbResLen != RFAL_NFCB_SENSB_RES_EXT_LEN))) {
  134. return ERR_PROTO;
  135. }
  136. /* Check SENSB_RES and Protocol Type Digital 1.1 7.6.2.19 */
  137. if(((sensbRes->protInfo.FsciProType & RFAL_NFCB_SENSB_RES_PROT_TYPE_RFU) != 0U) ||
  138. (sensbRes->cmd != (uint8_t)RFAL_NFCB_CMD_SENSB_RES)) {
  139. return ERR_PROTO;
  140. }
  141. return ERR_NONE;
  142. }
  143. /*
  144. ******************************************************************************
  145. * GLOBAL FUNCTIONS
  146. ******************************************************************************
  147. */
  148. /*******************************************************************************/
  149. ReturnCode rfalNfcbPollerInitialize(void) {
  150. ReturnCode ret;
  151. EXIT_ON_ERR(ret, rfalSetMode(RFAL_MODE_POLL_NFCB, RFAL_BR_106, RFAL_BR_106));
  152. rfalSetErrorHandling(RFAL_ERRORHANDLING_NFC);
  153. rfalSetGT(RFAL_GT_NFCB);
  154. rfalSetFDTListen(RFAL_FDT_LISTEN_NFCB_POLLER);
  155. rfalSetFDTPoll(RFAL_FDT_POLL_NFCB_POLLER);
  156. gRfalNfcb.AFI = RFAL_NFCB_AFI;
  157. gRfalNfcb.PARAM = RFAL_NFCB_PARAM;
  158. return ERR_NONE;
  159. }
  160. /*******************************************************************************/
  161. ReturnCode rfalNfcbPollerInitializeWithParams(uint8_t AFI, uint8_t PARAM) {
  162. ReturnCode ret;
  163. EXIT_ON_ERR(ret, rfalNfcbPollerInitialize());
  164. gRfalNfcb.AFI = AFI;
  165. gRfalNfcb.PARAM = (PARAM & RFAL_NFCB_SENSB_REQ_PARAM);
  166. return ERR_NONE;
  167. }
  168. /*******************************************************************************/
  169. ReturnCode rfalNfcbPollerCheckPresence(
  170. rfalNfcbSensCmd cmd,
  171. rfalNfcbSlots slots,
  172. rfalNfcbSensbRes* sensbRes,
  173. uint8_t* sensbResLen) {
  174. uint16_t rxLen;
  175. ReturnCode ret;
  176. rfalNfcbSensbReq sensbReq;
  177. /* Check if the command requested and given the slot number are valid */
  178. if(((RFAL_NFCB_SENS_CMD_SENSB_REQ != cmd) && (RFAL_NFCB_SENS_CMD_ALLB_REQ != cmd)) ||
  179. (slots > RFAL_NFCB_SLOT_NUM_16) || (sensbRes == NULL) || (sensbResLen == NULL)) {
  180. return ERR_PARAM;
  181. }
  182. *sensbResLen = 0;
  183. ST_MEMSET(sensbRes, 0x00, sizeof(rfalNfcbSensbRes));
  184. /* Compute SENSB_REQ */
  185. sensbReq.cmd = RFAL_NFCB_CMD_SENSB_REQ;
  186. sensbReq.AFI = gRfalNfcb.AFI;
  187. sensbReq.PARAM =
  188. (((uint8_t)gRfalNfcb.PARAM & RFAL_NFCB_SENSB_REQ_PARAM) | (uint8_t)cmd | (uint8_t)slots);
  189. /* Send SENSB_REQ and disable AGC to detect collisions */
  190. ret = rfalTransceiveBlockingTxRx(
  191. (uint8_t*)&sensbReq,
  192. sizeof(rfalNfcbSensbReq),
  193. (uint8_t*)sensbRes,
  194. sizeof(rfalNfcbSensbRes),
  195. &rxLen,
  196. RFAL_TXRX_FLAGS_DEFAULT,
  197. RFAL_NFCB_FWTSENSB);
  198. *sensbResLen = (uint8_t)rxLen;
  199. /* Check if a transmission error was detected */
  200. if((ret == ERR_CRC) || (ret == ERR_FRAMING)) {
  201. /* Invalidate received frame as an error was detected (CollisionResolution checks if valid) */
  202. *sensbResLen = 0;
  203. return ERR_NONE;
  204. }
  205. if(ret == ERR_NONE) {
  206. return rfalNfcbCheckSensbRes(sensbRes, *sensbResLen);
  207. }
  208. return ret;
  209. }
  210. /*******************************************************************************/
  211. ReturnCode rfalNfcbPollerSleep(const uint8_t* nfcid0) {
  212. uint16_t rxLen;
  213. ReturnCode ret;
  214. rfalNfcbSlpbReq slpbReq;
  215. rfalNfcbSlpbRes slpbRes;
  216. if(nfcid0 == NULL) {
  217. return ERR_PARAM;
  218. }
  219. /* Compute SLPB_REQ */
  220. slpbReq.cmd = RFAL_NFCB_CMD_SLPB_REQ;
  221. ST_MEMCPY(slpbReq.nfcid0, nfcid0, RFAL_NFCB_NFCID0_LEN);
  222. EXIT_ON_ERR(
  223. ret,
  224. rfalTransceiveBlockingTxRx(
  225. (uint8_t*)&slpbReq,
  226. sizeof(rfalNfcbSlpbReq),
  227. (uint8_t*)&slpbRes,
  228. sizeof(rfalNfcbSlpbRes),
  229. &rxLen,
  230. RFAL_TXRX_FLAGS_DEFAULT,
  231. RFAL_NFCB_ACTIVATION_FWT));
  232. /* Check SLPB_RES */
  233. if((rxLen != sizeof(rfalNfcbSlpbRes)) || (slpbRes.cmd != (uint8_t)RFAL_NFCB_CMD_SLPB_RES)) {
  234. return ERR_PROTO;
  235. }
  236. return ERR_NONE;
  237. }
  238. /*******************************************************************************/
  239. ReturnCode
  240. rfalNfcbPollerSlotMarker(uint8_t slotCode, rfalNfcbSensbRes* sensbRes, uint8_t* sensbResLen) {
  241. ReturnCode ret;
  242. rfalNfcbSlotMarker slotMarker;
  243. uint16_t rxLen;
  244. /* Check parameters */
  245. if((sensbRes == NULL) || (sensbResLen == NULL) ||
  246. (slotCode < RFAL_NFCB_SLOTMARKER_SLOTCODE_MIN) ||
  247. (slotCode > RFAL_NFCB_SLOTMARKER_SLOTCODE_MAX)) {
  248. return ERR_PARAM;
  249. }
  250. /* Compose and send SLOT_MARKER with disabled AGC to detect collisions */
  251. slotMarker.APn =
  252. ((slotCode << RFAL_NFCB_SLOT_MARKER_SC_SHIFT) | (uint8_t)RFAL_NFCB_CMD_SENSB_REQ);
  253. ret = rfalTransceiveBlockingTxRx(
  254. (uint8_t*)&slotMarker,
  255. sizeof(rfalNfcbSlotMarker),
  256. (uint8_t*)sensbRes,
  257. sizeof(rfalNfcbSensbRes),
  258. &rxLen,
  259. RFAL_TXRX_FLAGS_DEFAULT,
  260. RFAL_NFCB_ACTIVATION_FWT);
  261. *sensbResLen = (uint8_t)rxLen;
  262. /* Check if a transmission error was detected */
  263. if((ret == ERR_CRC) || (ret == ERR_FRAMING)) {
  264. return ERR_RF_COLLISION;
  265. }
  266. if(ret == ERR_NONE) {
  267. return rfalNfcbCheckSensbRes(sensbRes, *sensbResLen);
  268. }
  269. return ret;
  270. }
  271. ReturnCode rfalNfcbPollerTechnologyDetection(
  272. rfalComplianceMode compMode,
  273. rfalNfcbSensbRes* sensbRes,
  274. uint8_t* sensbResLen) {
  275. NO_WARNING(compMode);
  276. return rfalNfcbPollerCheckPresence(
  277. RFAL_NFCB_SENS_CMD_SENSB_REQ, RFAL_NFCB_SLOT_NUM_1, sensbRes, sensbResLen);
  278. }
  279. /*******************************************************************************/
  280. ReturnCode rfalNfcbPollerCollisionResolution(
  281. rfalComplianceMode compMode,
  282. uint8_t devLimit,
  283. rfalNfcbListenDevice* nfcbDevList,
  284. uint8_t* devCnt) {
  285. bool colPending; /* dummy */
  286. return rfalNfcbPollerSlottedCollisionResolution(
  287. compMode,
  288. devLimit,
  289. RFAL_NFCB_SLOT_NUM_1,
  290. RFAL_NFCB_SLOT_NUM_16,
  291. nfcbDevList,
  292. devCnt,
  293. &colPending);
  294. }
  295. /*******************************************************************************/
  296. ReturnCode rfalNfcbPollerSlottedCollisionResolution(
  297. rfalComplianceMode compMode,
  298. uint8_t devLimit,
  299. rfalNfcbSlots initSlots,
  300. rfalNfcbSlots endSlots,
  301. rfalNfcbListenDevice* nfcbDevList,
  302. uint8_t* devCnt,
  303. bool* colPending) {
  304. ReturnCode ret;
  305. uint8_t slotsNum;
  306. uint8_t slotCode;
  307. uint8_t curDevCnt;
  308. /* Check parameters. In ISO | Activity 1.0 mode the initial slots must be 1 as continuation of Technology Detection */
  309. if((nfcbDevList == NULL) || (devCnt == NULL) || (colPending == NULL) ||
  310. (initSlots > RFAL_NFCB_SLOT_NUM_16) || (endSlots > RFAL_NFCB_SLOT_NUM_16) ||
  311. ((compMode == RFAL_COMPLIANCE_MODE_ISO) && (initSlots != RFAL_NFCB_SLOT_NUM_1))) {
  312. return ERR_PARAM;
  313. }
  314. /* Initialise as no error in case Activity 1.0 where the previous SENSB_RES from technology detection should be used */
  315. ret = ERR_NONE;
  316. *devCnt = 0;
  317. curDevCnt = 0;
  318. *colPending = false;
  319. /* Send ALLB_REQ Activity 1.1 9.3.5.2 and 9.3.5.3 (Symbol 1 and 2) */
  320. if(compMode != RFAL_COMPLIANCE_MODE_ISO) {
  321. ret = rfalNfcbPollerCheckPresence(
  322. RFAL_NFCB_SENS_CMD_ALLB_REQ,
  323. initSlots,
  324. &nfcbDevList->sensbRes,
  325. &nfcbDevList->sensbResLen);
  326. if((ret != ERR_NONE) && (initSlots == RFAL_NFCB_SLOT_NUM_1)) {
  327. return ret;
  328. }
  329. }
  330. /* Check if there was a transmission error on WUPB EMVCo 2.6 9.3.3.1 */
  331. if((compMode == RFAL_COMPLIANCE_MODE_EMV) && (nfcbDevList->sensbResLen == 0U)) {
  332. return ERR_FRAMING;
  333. }
  334. for(slotsNum = (uint8_t)initSlots; slotsNum <= (uint8_t)endSlots; slotsNum++) {
  335. do {
  336. /* Activity 1.1 9.3.5.23 - Symbol 22 */
  337. if((compMode == RFAL_COMPLIANCE_MODE_NFC) && (curDevCnt != 0U)) {
  338. rfalNfcbPollerSleep(nfcbDevList[((*devCnt) - (uint8_t)1U)].sensbRes.nfcid0);
  339. nfcbDevList[((*devCnt) - (uint8_t)1U)].isSleep = true;
  340. }
  341. /* Send SENSB_REQ with number of slots if not the first Activity 1.1 9.3.5.24 - Symbol 23 */
  342. if((slotsNum != (uint8_t)initSlots) || *colPending) {
  343. /* PRQA S 4342 1 # MISRA 10.5 - Layout of rfalNfcbSlots and above loop guarantee that no invalid enum values are created. */
  344. ret = rfalNfcbPollerCheckPresence(
  345. RFAL_NFCB_SENS_CMD_SENSB_REQ,
  346. (rfalNfcbSlots)slotsNum,
  347. &nfcbDevList[*devCnt].sensbRes,
  348. &nfcbDevList[*devCnt].sensbResLen);
  349. }
  350. /* Activity 1.1 9.3.5.6 - Symbol 5 */
  351. slotCode = 0;
  352. curDevCnt = 0;
  353. *colPending = false;
  354. do {
  355. /* Activity 1.1 9.3.5.26 - Symbol 25 */
  356. if(slotCode != 0U) {
  357. ret = rfalNfcbPollerSlotMarker(
  358. slotCode,
  359. &nfcbDevList[*devCnt].sensbRes,
  360. &nfcbDevList[*devCnt].sensbResLen);
  361. }
  362. /* Activity 1.1 9.3.5.7 and 9.3.5.8 - Symbol 6 */
  363. if(ret != ERR_TIMEOUT) {
  364. /* Activity 1.1 9.3.5.8 - Symbol 7 */
  365. if((rfalNfcbCheckSensbRes(
  366. &nfcbDevList[*devCnt].sensbRes, nfcbDevList[*devCnt].sensbResLen) ==
  367. ERR_NONE) &&
  368. (ret == ERR_NONE)) {
  369. nfcbDevList[*devCnt].isSleep = false;
  370. if(compMode == RFAL_COMPLIANCE_MODE_EMV) {
  371. (*devCnt)++;
  372. return ret;
  373. } else if(compMode == RFAL_COMPLIANCE_MODE_ISO) {
  374. /* Activity 1.0 9.3.5.8 - Symbol 7 */
  375. (*devCnt)++;
  376. curDevCnt++;
  377. /* Activity 1.0 9.3.5.10 - Symbol 9 */
  378. if((*devCnt >= devLimit) ||
  379. (slotsNum == (uint8_t)RFAL_NFCB_SLOT_NUM_1)) {
  380. return ret;
  381. }
  382. /* Activity 1.0 9.3.5.11 - Symbol 10 */
  383. rfalNfcbPollerSleep(nfcbDevList[*devCnt - 1U].sensbRes.nfcid0);
  384. nfcbDevList[*devCnt - 1U].isSleep = true;
  385. } else if(compMode == RFAL_COMPLIANCE_MODE_NFC) {
  386. /* Activity 1.1 9.3.5.10 and 9.3.5.11 - Symbol 9 and Symbol 11*/
  387. if(curDevCnt != 0U) {
  388. rfalNfcbPollerSleep(
  389. nfcbDevList[(*devCnt) - (uint8_t)1U].sensbRes.nfcid0);
  390. nfcbDevList[(*devCnt) - (uint8_t)1U].isSleep = true;
  391. }
  392. /* Activity 1.1 9.3.5.12 - Symbol 11 */
  393. (*devCnt)++;
  394. curDevCnt++;
  395. /* Activity 1.1 9.3.5.6 - Symbol 13 */
  396. if((*devCnt >= devLimit) ||
  397. (slotsNum == (uint8_t)RFAL_NFCB_SLOT_NUM_1)) {
  398. return ret;
  399. }
  400. } else {
  401. /* MISRA 15.7 - Empty else */
  402. }
  403. } else {
  404. /* If deviceLimit is set to 0 the NFC Forum Device is configured to perform collision detection only Activity 1.0 and 1.1 9.3.5.5 - Symbol 4 */
  405. if((devLimit == 0U) && (slotsNum == (uint8_t)RFAL_NFCB_SLOT_NUM_1)) {
  406. return ERR_RF_COLLISION;
  407. }
  408. /* Activity 1.1 9.3.5.9 - Symbol 8 */
  409. *colPending = true;
  410. }
  411. }
  412. /* Activity 1.1 9.3.5.15 - Symbol 14 */
  413. slotCode++;
  414. } while(slotCode < rfalNfcbNI2NumberOfSlots(slotsNum));
  415. /* Activity 1.1 9.3.5.17 - Symbol 16 */
  416. if(!(*colPending)) {
  417. return ERR_NONE;
  418. }
  419. /* Activity 1.1 9.3.5.18 - Symbol 17 */
  420. } while(
  421. curDevCnt !=
  422. 0U); /* If a collision is detected and card(s) were found on this loop keep the same number of available slots */
  423. }
  424. return ERR_NONE;
  425. }
  426. /*******************************************************************************/
  427. uint32_t rfalNfcbTR2ToFDT(uint8_t tr2Code) {
  428. /*******************************************************************************/
  429. /* MISRA 8.9 An object should be defined at block scope if its identifier only appears in a single function */
  430. /*! TR2 Table according to Digital 1.1 Table 33 */
  431. const uint16_t rfalNfcbTr2Table[] = {1792, 3328, 5376, 9472};
  432. /*******************************************************************************/
  433. return rfalNfcbTr2Table[(tr2Code & RFAL_NFCB_SENSB_RES_PROTO_TR2_MASK)];
  434. }
  435. #endif /* RFAL_FEATURE_NFCB */