rfal_t2t.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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_t2t.c
  27. *
  28. * \author
  29. *
  30. * \brief Provides NFC-A T2T convenience methods and definitions
  31. *
  32. * This module provides an interface to perform as a NFC-A Reader/Writer
  33. * to handle a Type 2 Tag T2T
  34. *
  35. */
  36. /*
  37. ******************************************************************************
  38. * INCLUDES
  39. ******************************************************************************
  40. */
  41. #include "../include/rfal_t2t.h"
  42. #include "../utils.h"
  43. /*
  44. ******************************************************************************
  45. * ENABLE SWITCH
  46. ******************************************************************************
  47. */
  48. #ifndef RFAL_FEATURE_T2T
  49. #define RFAL_FEATURE_T2T false /* T2T module configuration missing. Disabled by default */
  50. #endif
  51. #if RFAL_FEATURE_T2T
  52. /*
  53. ******************************************************************************
  54. * GLOBAL DEFINES
  55. ******************************************************************************
  56. */
  57. #define RFAL_FDT_POLL_READ_MAX \
  58. rfalConvMsTo1fc( \
  59. 5U) /*!< Maximum Wait time for Read command as defined in TS T2T 1.0 table 18 */
  60. #define RFAL_FDT_POLL_WRITE_MAX \
  61. rfalConvMsTo1fc( \
  62. 10U) /*!< Maximum Wait time for Write command as defined in TS T2T 1.0 table 18 */
  63. #define RFAL_FDT_POLL_SL_MAX \
  64. rfalConvMsTo1fc( \
  65. 1U) /*!< Maximum Wait time for Sector Select as defined in TS T2T 1.0 table 18 */
  66. #define RFAL_T2T_ACK_NACK_LEN \
  67. 1U /*!< Len of NACK in bytes (4 bits) */
  68. #define RFAL_T2T_ACK \
  69. 0x0AU /*!< ACK value */
  70. #define RFAL_T2T_ACK_MASK \
  71. 0x0FU /*!< ACK value */
  72. #define RFAL_T2T_SECTOR_SELECT_P1_BYTE2 \
  73. 0xFFU /*!< Sector Select Packet 1 byte 2 */
  74. #define RFAL_T2T_SECTOR_SELECT_P2_RFU_LEN \
  75. 3U /*!< Sector Select RFU length */
  76. /*
  77. ******************************************************************************
  78. * GLOBAL TYPES
  79. ******************************************************************************
  80. */
  81. /*! NFC-A T2T command set T2T 1.0 5.1 */
  82. typedef enum {
  83. RFAL_T2T_CMD_READ = 0x30, /*!< T2T Read */
  84. RFAL_T2T_CMD_WRITE = 0xA2, /*!< T2T Write */
  85. RFAL_T2T_CMD_SECTOR_SELECT = 0xC2 /*!< T2T Sector Select */
  86. } rfalT2Tcmds;
  87. /*! NFC-A T2T READ T2T 1.0 5.2 and table 11 */
  88. typedef struct {
  89. uint8_t code; /*!< Command code */
  90. uint8_t blNo; /*!< Block number */
  91. } rfalT2TReadReq;
  92. /*! NFC-A T2T WRITE T2T 1.0 5.3 and table 12 */
  93. typedef struct {
  94. uint8_t code; /*!< Command code */
  95. uint8_t blNo; /*!< Block number */
  96. uint8_t data[RFAL_T2T_WRITE_DATA_LEN]; /*!< Data */
  97. } rfalT2TWriteReq;
  98. /*! NFC-A T2T SECTOR SELECT Packet 1 T2T 1.0 5.4 and table 13 */
  99. typedef struct {
  100. uint8_t code; /*!< Command code */
  101. uint8_t byte2; /*!< Sector Select Packet 1 byte 2 */
  102. } rfalT2TSectorSelectP1Req;
  103. /*! NFC-A T2T SECTOR SELECT Packet 2 T2T 1.0 5.4 and table 13 */
  104. typedef struct {
  105. uint8_t secNo; /*!< Block number */
  106. uint8_t rfu[RFAL_T2T_SECTOR_SELECT_P2_RFU_LEN]; /*!< Sector Select Packet RFU */
  107. } rfalT2TSectorSelectP2Req;
  108. /*
  109. ******************************************************************************
  110. * GLOBAL FUNCTIONS
  111. ******************************************************************************
  112. */
  113. ReturnCode
  114. rfalT2TPollerRead(uint8_t blockNum, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* rcvLen) {
  115. ReturnCode ret;
  116. rfalT2TReadReq req;
  117. if((rxBuf == NULL) || (rcvLen == NULL)) {
  118. return ERR_PARAM;
  119. }
  120. req.code = (uint8_t)RFAL_T2T_CMD_READ;
  121. req.blNo = blockNum;
  122. /* Transceive Command */
  123. ret = rfalTransceiveBlockingTxRx(
  124. (uint8_t*)&req,
  125. sizeof(rfalT2TReadReq),
  126. rxBuf,
  127. rxBufLen,
  128. rcvLen,
  129. RFAL_TXRX_FLAGS_DEFAULT,
  130. RFAL_FDT_POLL_READ_MAX);
  131. /* T2T 1.0 5.2.1.7 The Reader/Writer SHALL treat a NACK in response to a READ Command as a Protocol Error */
  132. if((ret == ERR_INCOMPLETE_BYTE) && (*rcvLen == RFAL_T2T_ACK_NACK_LEN) &&
  133. ((*rxBuf & RFAL_T2T_ACK_MASK) != RFAL_T2T_ACK)) {
  134. return ERR_PROTO;
  135. }
  136. return ret;
  137. }
  138. /*******************************************************************************/
  139. ReturnCode rfalT2TPollerWrite(uint8_t blockNum, const uint8_t* wrData) {
  140. ReturnCode ret;
  141. rfalT2TWriteReq req;
  142. uint8_t res;
  143. uint16_t rxLen;
  144. req.code = (uint8_t)RFAL_T2T_CMD_WRITE;
  145. req.blNo = blockNum;
  146. ST_MEMCPY(req.data, wrData, RFAL_T2T_WRITE_DATA_LEN);
  147. /* Transceive WRITE Command */
  148. ret = rfalTransceiveBlockingTxRx(
  149. (uint8_t*)&req,
  150. sizeof(rfalT2TWriteReq),
  151. &res,
  152. sizeof(uint8_t),
  153. &rxLen,
  154. RFAL_TXRX_FLAGS_DEFAULT,
  155. RFAL_FDT_POLL_READ_MAX);
  156. /* Check for a valid ACK */
  157. if((ret == ERR_INCOMPLETE_BYTE) || (ret == ERR_NONE)) {
  158. ret = ERR_PROTO;
  159. if((rxLen == RFAL_T2T_ACK_NACK_LEN) && ((res & RFAL_T2T_ACK_MASK) == RFAL_T2T_ACK)) {
  160. ret = ERR_NONE;
  161. }
  162. }
  163. return ret;
  164. }
  165. /*******************************************************************************/
  166. ReturnCode rfalT2TPollerSectorSelect(uint8_t sectorNum) {
  167. rfalT2TSectorSelectP1Req p1Req;
  168. rfalT2TSectorSelectP2Req p2Req;
  169. ReturnCode ret;
  170. uint8_t res;
  171. uint16_t rxLen;
  172. /* Compute SECTOR SELECT Packet 1 */
  173. p1Req.code = (uint8_t)RFAL_T2T_CMD_SECTOR_SELECT;
  174. p1Req.byte2 = RFAL_T2T_SECTOR_SELECT_P1_BYTE2;
  175. /* Transceive SECTOR SELECT Packet 1 */
  176. ret = rfalTransceiveBlockingTxRx(
  177. (uint8_t*)&p1Req,
  178. sizeof(rfalT2TSectorSelectP1Req),
  179. &res,
  180. sizeof(uint8_t),
  181. &rxLen,
  182. RFAL_TXRX_FLAGS_DEFAULT,
  183. RFAL_FDT_POLL_SL_MAX);
  184. /* Check and report any transmission error */
  185. if((ret != ERR_INCOMPLETE_BYTE) && (ret != ERR_NONE)) {
  186. return ret;
  187. }
  188. /* Ensure that an ACK was received */
  189. if((ret != ERR_INCOMPLETE_BYTE) || (rxLen != RFAL_T2T_ACK_NACK_LEN) ||
  190. ((res & RFAL_T2T_ACK_MASK) != RFAL_T2T_ACK)) {
  191. return ERR_PROTO;
  192. }
  193. /* Compute SECTOR SELECT Packet 2 */
  194. p2Req.secNo = sectorNum;
  195. ST_MEMSET(&p2Req.rfu, 0x00, RFAL_T2T_SECTOR_SELECT_P2_RFU_LEN);
  196. /* Transceive SECTOR SELECT Packet 2 */
  197. ret = rfalTransceiveBlockingTxRx(
  198. (uint8_t*)&p2Req,
  199. sizeof(rfalT2TSectorSelectP2Req),
  200. &res,
  201. sizeof(uint8_t),
  202. &rxLen,
  203. RFAL_TXRX_FLAGS_DEFAULT,
  204. RFAL_FDT_POLL_SL_MAX);
  205. /* T2T 1.0 5.4.1.14 The Reader/Writer SHALL treat any response received before the end of PATT2T,SL,MAX as a Protocol Error */
  206. if((ret == ERR_NONE) || (ret == ERR_INCOMPLETE_BYTE)) {
  207. return ERR_PROTO;
  208. }
  209. /* T2T 1.0 5.4.1.13 The Reader/Writer SHALL treat the transmission of the SECTOR SELECT Command Packet 2 as being successful when it receives no response until PATT2T,SL,MAX. */
  210. if(ret == ERR_TIMEOUT) {
  211. return ERR_NONE;
  212. }
  213. return ret;
  214. }
  215. #endif /* RFAL_FEATURE_T2T */