PageRenderTime 76ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 0ms

/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c

https://gitlab.com/ubicore/nRF5_SDK_11.0.0_89a8197
C | 859 lines | 575 code | 160 blank | 124 comment | 65 complexity | 5e3c35adffebf4c283691b017f3ad080 MD5 | raw file
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "hal_nfc_t2t.h"
  13. #include <stdint.h>
  14. #include <stdbool.h>
  15. #include "nfc_t2t_lib.h"
  16. #include "nfc_fixes.h"
  17. #include "nrf.h"
  18. #include "app_util_platform.h"
  19. #include "nordic_common.h"
  20. #include "hal_nfc_t2t_logger.h"
  21. #include "nrf_drv_clock.h"
  22. // Pin for debug signals
  23. #define HCLOCK_ON_PIN 11
  24. #define HCLOCK_OFF_PIN 12
  25. #define NFC_EVENT_PIN 24
  26. #define DETECT_EVENT_PIN 25
  27. #define TIMER4_EVENT_PIN 28
  28. #ifdef HAL_NFC_DEBUG_PIN_ENABLE
  29. #include "nrf_gpio.h"
  30. #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num)
  31. #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num)
  32. #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num)
  33. #define HAL_NFC_DEBUG_PINS_INITIALIZE() \
  34. HAL_NFC_DEBUG_PIN_CONFIG(HCLOCK_OFF_PIN); \
  35. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); \
  36. HAL_NFC_DEBUG_PIN_CONFIG(HCLOCK_ON_PIN); \
  37. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); \
  38. HAL_NFC_DEBUG_PIN_CONFIG(NFC_EVENT_PIN); \
  39. HAL_NFC_DEBUG_PIN_CLEAR(NFC_EVENT_PIN); \
  40. HAL_NFC_DEBUG_PIN_CONFIG(DETECT_EVENT_PIN); \
  41. HAL_NFC_DEBUG_PIN_CLEAR(DETECT_EVENT_PIN); \
  42. HAL_NFC_DEBUG_PIN_CONFIG(TIMER4_EVENT_PIN); \
  43. HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN)
  44. #else
  45. #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num)
  46. #define HAL_NFC_DEBUG_PIN_SET(pin_num)
  47. #define HAL_NFC_DEBUG_PINS_INITIALIZE()
  48. #endif // HAL_NFC_DEBUG_PIN_ENABLE
  49. /* NFC library version history:
  50. * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit)
  51. * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit)
  52. * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode
  53. */
  54. #define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */
  55. #define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */
  56. #define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */
  57. #define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */
  58. #define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */
  59. #define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */
  60. #define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */
  61. #define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */
  62. #define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */
  63. #define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */
  64. #define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
  65. #define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
  66. #define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
  67. #define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */
  68. #define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
  69. #define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
  70. #define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
  71. #define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */
  72. #define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */
  73. #define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */
  74. #define NFC_CRC_SIZE 2u /**< CRC size in bytes */
  75. #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \
  76. NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \
  77. NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */
  78. #define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \
  79. NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \
  80. NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */
  81. #define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk ///< Mask for checking FIELDPRESENT register for state: FIELD ON.
  82. #define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk ///< Mask for checking FIELDPRESENT register for state: FIELD OFF.
  83. typedef enum
  84. {
  85. NFC_FIELD_STATE_NONE, ///< Initial value indicating no NFCT Field events.
  86. NFC_FIELD_STATE_OFF, ///< NFCT FIELDLOST Event has been set.
  87. NFC_FIELD_STATE_ON, ///< NFCT FIELDDETECTED Event has been set.
  88. NFC_FIELD_STATE_UNKNOWN ///< Both NFCT Field Events have been set - ambiguous state.
  89. }nfct_field_sense_state_t;
  90. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  91. /* Begin: Bugfix for FTPAN-57 (IC-9563) */
  92. #define NRF_NFCT_SHUNTREGTHRESHOLDS (*(uint32_t volatile *)(0x40005610))
  93. #define NRF_NFCT_MODSTEPFIXED (*(uint32_t volatile *)(0x40005614))
  94. #define NRF_NFCT_MODSTEPMULTIPLIER (*(uint32_t volatile *)(0x40005618))
  95. #define NRF_NFCT_INITIALLOADCTRLVAL (*(uint32_t volatile *)(0x40005688))
  96. /* End: Bugfix for FTPAN-57 (IC-9563) */
  97. /* Begin: Bugfix for FTPAN-24 */
  98. #define NRF_NFCT_AUTOCOLRESSTATUS (*(uint32_t volatile *)(0x40005408))
  99. /* End: Bugfix for FTPAN-24 */
  100. /* Begin: Bugfix for FTPAN-27 */
  101. #define NRF_NFCT_TASKS_DISABLERXDATA (*(uint32_t volatile *)(0x40005020))
  102. /* End: Bugfix for FTPAN-27 */
  103. /* Begin: Bugfix for FTPAN-17 */
  104. #define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | NFCT_FIELDPRESENT_FIELDPRESENT_Msk)
  105. #define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) \
  106. |(NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << NFCT_FIELDPRESENT_LOCKDETECT_Pos))
  107. #define NFC_HAL_FIELDPRESENT_NO_FIELD (NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos)
  108. /* End: Bugfix for FTPAN-17*/
  109. static void hal_nfc_field_check(void);
  110. #endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  111. /* Static function declarations */
  112. static inline void nrf_nfct_event_clear(volatile uint32_t * p_event);
  113. static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event);
  114. static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state);
  115. /* Static data */
  116. static hal_nfc_callback m_nfc_lib_callback = (hal_nfc_callback) NULL; /**< Callback to nfc_lib layer */
  117. static void * m_nfc_lib_context; /**< Callback execution context */
  118. static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */
  119. static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */
  120. #ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  121. static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */
  122. #endif
  123. static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */
  124. static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */
  125. #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  126. static inline void hal_nfc_re_setup(void);
  127. static void hal_nfc_field_check(void);
  128. #define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | NFCT_FIELDPRESENT_FIELDPRESENT_Msk)
  129. #define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) \
  130. |(NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << NFCT_FIELDPRESENT_LOCKDETECT_Pos))
  131. #define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC))
  132. #endif
  133. #if defined(HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND) || defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND)
  134. static void field_timer_with_callback_config()
  135. {
  136. NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
  137. NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos;
  138. NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
  139. NRF_TIMER4->CC[0] = 100 << TIMER_CC_CC_Pos;
  140. NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
  141. NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;
  142. NVIC_ClearPendingIRQ(TIMER4_IRQn);
  143. NVIC_SetPriority(TIMER4_IRQn, APP_IRQ_PRIORITY_LOW);
  144. NVIC_EnableIRQ(TIMER4_IRQn);
  145. }
  146. void TIMER4_IRQHandler(void)
  147. {
  148. HAL_NFC_DEBUG_PIN_SET(TIMER4_EVENT_PIN);
  149. hal_nfc_field_check();
  150. NRF_TIMER4->EVENTS_COMPARE[0] = 0;
  151. HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN);
  152. }
  153. #endif
  154. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  155. /* Begin: Bugfix for FTPAN-45 (IC-6915) */
  156. volatile uint8_t m_nfc_active = 0;
  157. /* End: Bugfix for FTPAN-45 (IC-6915) */
  158. /* Begin: Bugfix for FTPAN-17 (IC-9563) */
  159. /* The following three function definitions are a workaround for IC-9563: NFC in nRF52 IC rev. Engineering A does not
  160. * give the field lost signal when field is turned off. */
  161. static bool field_on = false;
  162. volatile bool hal_nfc_fielddetected = false;
  163. volatile bool hal_nfc_fieldlost = false;
  164. static void hal_nfc_field_check(void)
  165. {
  166. static uint32_t field_state_cnt = 0;
  167. volatile uint32_t dummy;
  168. uint32_t nfc_fieldpresen_masked;
  169. /* Begin: Bugfix for FTPAN-24 */
  170. NRF_NFCT_AUTOCOLRESSTATUS = 0; /* dummy write - no effect. */
  171. NRF_NFCT_AUTOCOLRESSTATUS = 0; /* dummy write - no effect. */
  172. // Don't worry about interrupted case - NRF_NFCT->FIELDPRESENT is read each 100 us, so the workaround should succeed most of the times.
  173. /* End: Bugfix for FTPAN-24 */
  174. nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK;
  175. if (field_on)
  176. {
  177. if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST)
  178. {
  179. ++field_state_cnt;
  180. if (field_state_cnt > 7)
  181. {
  182. field_state_cnt = 0;
  183. hal_nfc_fieldlost = true;
  184. dummy = hal_nfc_fieldlost;
  185. field_on = false;
  186. NVIC_SetPendingIRQ(NFCT_IRQn);
  187. UNUSED_VARIABLE(dummy);
  188. }
  189. return;
  190. }
  191. }
  192. else
  193. {
  194. nfc_fieldpresen_masked &= NFCT_FIELDPRESENT_FIELDPRESENT_Msk;
  195. if (nfc_fieldpresen_masked != NFC_HAL_FIELDPRESENT_NO_FIELD)
  196. {
  197. ++field_state_cnt;
  198. if (field_state_cnt > 7)
  199. {
  200. field_state_cnt = 0;
  201. hal_nfc_fielddetected = true;
  202. dummy = hal_nfc_fielddetected;
  203. field_on = true;
  204. NVIC_SetPendingIRQ(NFCT_IRQn);
  205. UNUSED_VARIABLE(dummy);
  206. }
  207. return;
  208. }
  209. }
  210. field_state_cnt = 0;
  211. }
  212. /* End: Bugfix for FTPAN-17, FTPAN-27 */
  213. #endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  214. /**
  215. * @brief Common part of setup used for NFCT initialization and reinitialization.
  216. */
  217. #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  218. static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal)
  219. #else
  220. static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal)
  221. #endif
  222. {
  223. uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0;
  224. uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1;
  225. /* Begin: Bugfix for FTPAN-17 */
  226. /* fixed by avoiding usage of FIELDLOST and FIELDETECTED events */
  227. #ifndef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  228. #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  229. NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos);
  230. #else
  231. NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) |
  232. (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos);
  233. #endif
  234. #endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  235. /* End: Bugfix for FTPAN-17 */
  236. NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) |
  237. (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos);
  238. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  239. /* Begin: Bugfix for FTPAN-45 (IC-6915) */
  240. NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMESTART_Enabled << NFCT_INTENSET_RXFRAMESTART_Pos) |
  241. (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos);
  242. /* End: Bugfix for FTPAN-45 (IC-6915) */
  243. #endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  244. /* According to ISO/IEC 14443-3 */
  245. nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); //SN0
  246. nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); //SN1
  247. nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); //SN2
  248. nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^
  249. nfc_internal[1] ^ nfc_internal[2]); //BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2
  250. nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); //SN3
  251. nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); //SN4
  252. nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); //SN5
  253. nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); //SN6
  254. nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^
  255. nfc_internal[6] ^ nfc_internal[7]); //BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6
  256. nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); //For internal use
  257. /* MSB of NFCID1_2ND_LAST register is not used - always 0 */
  258. NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) |
  259. ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) |
  260. ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT);
  261. NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) |
  262. ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) |
  263. ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) |
  264. ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT);
  265. /* Begin: Bugfix for FTPAN-25 (IC-9929) */
  266. /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
  267. because it's required to operate with Windows Phone */
  268. NRF_NFCT->SENSRES =
  269. (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) |
  270. (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos);
  271. /* End: Bugfix for FTPAN-25 (IC-9929)*/
  272. }
  273. hal_nfc_retval hal_nfc_setup(hal_nfc_callback callback, void *cbContext)
  274. {
  275. uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR];
  276. m_nfc_lib_callback = callback;
  277. m_nfc_lib_context = cbContext;
  278. hal_nfc_common_hw_setup(nfc_internal);
  279. (void) nfcSetInternal((char *) nfc_internal, sizeof(nfc_internal));
  280. /* Initialize SDK Clock module for handling high precission clock requests */
  281. m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler;
  282. m_clock_handler_item.p_next = NULL;
  283. ret_code_t err_code = nrf_drv_clock_init();
  284. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  285. /* Begin: Bugfix for FTPAN-57 (IC-9563) */
  286. /* Values taken from IC-9563 */
  287. NRF_NFCT_SHUNTREGTHRESHOLDS = 0x00000005;
  288. NRF_NFCT_MODSTEPFIXED = 0x0000003F;
  289. NRF_NFCT_MODSTEPMULTIPLIER = 0x00000001;
  290. NRF_NFCT_INITIALLOADCTRLVAL = 0x00000001;
  291. /* End: Bugfix for FTPAN-57 (IC-9563) */
  292. /* Begin: Bugfix for FTPAN-17 (IC-9563) */
  293. /* Activating workaround. */
  294. field_timer_with_callback_config();
  295. NRF_TIMER4->TASKS_START = 1;
  296. /* End: Bugfix for FTPAN-17 (IC-9563) */
  297. #endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  298. #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  299. field_timer_with_callback_config();
  300. #endif
  301. LOG_HAL_NFC("[NFC_HAL]: initialize\r\n");
  302. HAL_NFC_DEBUG_PINS_INITIALIZE();
  303. if ((err_code == NRF_SUCCESS) || (err_code == MODULE_ALREADY_INITIALIZED))
  304. {
  305. return HAL_NFC_RETVAL_OK;
  306. }
  307. else
  308. {
  309. return HAL_NFC_RETVAL_ERROR;
  310. }
  311. }
  312. /**@brief Function for clearing an event flag in NRF_NFCT registers.
  313. *
  314. * @param[in] p_event Pointer to event register.
  315. *
  316. */
  317. static inline void nrf_nfct_event_clear(volatile uint32_t * p_event)
  318. {
  319. *p_event = 0;
  320. /* Perform read to ensure clearing is effective */
  321. volatile uint32_t dummy = *p_event;
  322. (void)dummy;
  323. }
  324. /**@brief Function for handling events from Clock Module.
  325. *
  326. * @param[in] event Clock event.
  327. *
  328. */
  329. static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event)
  330. {
  331. switch(event)
  332. {
  333. case NRF_DRV_CLOCK_EVT_HFCLK_STARTED:
  334. /* Activate NFCT only when HFXO is running */
  335. HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG!
  336. NRF_NFCT->TASKS_ACTIVATE = 1;
  337. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG!
  338. break;
  339. default:
  340. /* No implementation required */
  341. break;
  342. }
  343. }
  344. #ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  345. /**@brief Function for evaluating and handling NFC field events.
  346. *
  347. * @param[in] field_state Current field state.
  348. *
  349. */
  350. static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
  351. {
  352. if (field_state == NFC_FIELD_STATE_UNKNOWN)
  353. {
  354. /* Probe NFC field */
  355. uint32_t field_present = NRF_NFCT->FIELDPRESENT;
  356. if (field_present & m_nfc_fieldpresent_mask)
  357. {
  358. field_state = NFC_FIELD_STATE_ON;
  359. }
  360. else
  361. {
  362. field_state = NFC_FIELD_STATE_OFF;
  363. }
  364. }
  365. /* Field event service */
  366. switch(field_state)
  367. {
  368. case NFC_FIELD_STATE_ON:
  369. if (!m_field_on)
  370. {
  371. HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG!
  372. nrf_drv_clock_hfclk_request(&m_clock_handler_item);
  373. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG!
  374. }
  375. m_field_on = true;
  376. break;
  377. case NFC_FIELD_STATE_OFF:
  378. HAL_NFC_DEBUG_PIN_SET(HCLOCK_OFF_PIN); //DEBUG!
  379. NRF_NFCT->TASKS_SENSE = 1;
  380. nrf_drv_clock_hfclk_release();
  381. //NRF_NFCT->TASKS_SENSE = 1;
  382. m_field_on = false;
  383. NRF_NFCT->INTENCLR =
  384. (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) |
  385. (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos);
  386. /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */
  387. m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK;
  388. if ((m_nfc_lib_callback != NULL) )
  389. {
  390. m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
  391. }
  392. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); //DEBUG!
  393. break;
  394. default:
  395. /* No implementation required */
  396. break;
  397. }
  398. }
  399. #endif
  400. /* This function is used by nfc_lib for unit testing only */
  401. hal_nfc_retval hal_nfc_set_parameter(hal_nfc_param_id id, void *data, size_t dataLength)
  402. {
  403. (void)id;
  404. (void)data;
  405. (void)dataLength;
  406. return HAL_NFC_RETVAL_OK;
  407. }
  408. /* This function is used by nfc_lib for unit testing only */
  409. hal_nfc_retval hal_nfc_get_parameter(hal_nfc_param_id id, void *data, size_t *maxDataLength)
  410. {
  411. (void)id;
  412. (void)data;
  413. (void)maxDataLength;
  414. return HAL_NFC_RETVAL_OK;
  415. }
  416. hal_nfc_retval hal_nfc_start(void)
  417. {
  418. NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
  419. NVIC_ClearPendingIRQ(NFCT_IRQn);
  420. NVIC_SetPriority(NFCT_IRQn, APP_IRQ_PRIORITY_LOW);
  421. NVIC_EnableIRQ(NFCT_IRQn);
  422. NRF_NFCT->TASKS_SENSE = 1;
  423. LOG_HAL_NFC("[NFC_HAL]: start\r\n");
  424. return HAL_NFC_RETVAL_OK;
  425. }
  426. hal_nfc_retval hal_nfc_send(const char *data, size_t dataLength)
  427. {
  428. if (dataLength == 0)
  429. {
  430. return HAL_NFC_RETVAL_INVALID_SIZE;
  431. }
  432. /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
  433. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
  434. NRF_NFCT->PACKETPTR = (uint32_t) data;
  435. NRF_NFCT->TXD.AMOUNT = (dataLength << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) &
  436. NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
  437. NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
  438. NRF_NFCT->TASKS_STARTTX = 1;
  439. LOG_HAL_NFC("[NFC_HAL]: send\r\n");
  440. return HAL_NFC_RETVAL_OK;
  441. }
  442. hal_nfc_retval hal_nfc_stop(void)
  443. {
  444. NRF_NFCT->TASKS_DISABLE = 1;
  445. LOG_HAL_NFC("[NFC_HAL]: stop\r\n");
  446. return HAL_NFC_RETVAL_OK;
  447. }
  448. hal_nfc_retval hal_nfc_done(void)
  449. {
  450. m_nfc_lib_callback = (hal_nfc_callback) NULL;
  451. return HAL_NFC_RETVAL_OK;
  452. }
  453. void NFCT_IRQHandler(void)
  454. {
  455. nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE;
  456. HAL_NFC_DEBUG_PIN_SET(NFC_EVENT_PIN); //DEBUG!
  457. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  458. /* Begin: Bugfix for FTPAN-27 */
  459. if (hal_nfc_fielddetected)
  460. {
  461. hal_nfc_fielddetected = false;
  462. NRF_NFCT_TASKS_DISABLERXDATA = 1;
  463. /* End: Bugfix for FTPAN-27 */
  464. #else
  465. if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk))
  466. {
  467. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED);
  468. #endif
  469. HAL_NFC_DEBUG_PIN_SET(DETECT_EVENT_PIN); //DEBUG!
  470. current_field = NFC_FIELD_STATE_ON;
  471. LOG_HAL_NFC("[NFC_HAL]: fielddetected\r\n");
  472. HAL_NFC_DEBUG_PIN_CLEAR(DETECT_EVENT_PIN); //DEBUG!
  473. }
  474. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  475. /* Begin: Bugfix for FTPAN-27 */
  476. if (hal_nfc_fieldlost)
  477. {
  478. hal_nfc_fieldlost = false;
  479. current_field =
  480. (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN;
  481. NRF_NFCT->TASKS_SENSE = 1;
  482. LOG_HAL_NFC("[NFC_HAL]: fieldlost\r\n");
  483. }
  484. /* End: Bugfix for FTPAN-27 */
  485. #elif !defined( HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND )
  486. if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk))
  487. {
  488. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST);
  489. current_field =
  490. (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN;
  491. LOG_HAL_NFC("[NFC_HAL]: fieldlost\r\n");
  492. }
  493. #endif
  494. /* Perform actions if any FIELD event is active */
  495. if (current_field != NFC_FIELD_STATE_NONE)
  496. {
  497. nrf_nfct_field_event_handler(current_field);
  498. }
  499. if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk))
  500. {
  501. /* Take into account only number of whole bytes */
  502. uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >>
  503. NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE;
  504. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
  505. /* Look for Tag 2 Type READ Command */
  506. if (m_nfc_rx_buffer[0] == T2T_READ_CMD)
  507. {
  508. if(m_nfc_lib_callback != NULL)
  509. {
  510. /* This callback should trigger transmission of READ Response */
  511. m_nfc_lib_callback(m_nfc_lib_context,
  512. HAL_NFC_EVENT_DATA_RECEIVED,
  513. (void*) m_nfc_rx_buffer,
  514. rx_data_size);
  515. }
  516. }
  517. else
  518. {
  519. /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */
  520. if(m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD)
  521. {
  522. m_slp_req_received = true;
  523. }
  524. /* Not a READ Command, so wait for next frame reception */
  525. NRF_NFCT->TASKS_ENABLERXDATA = 1;
  526. }
  527. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  528. /* Begin: Bugfix for FTPAN-45 (IC-6915) */
  529. m_nfc_active = 0;
  530. /* End: Bugfix for FTPAN-45 (IC-69150) */
  531. #endif
  532. LOG_HAL_NFC("[NFC_HAL]: rx_fend\r\n");
  533. }
  534. if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk))
  535. {
  536. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
  537. /* Disable TX END event to ignore frame transmission other than READ response */
  538. NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos);
  539. /* Set up for reception */
  540. NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
  541. NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
  542. NRF_NFCT->TASKS_ENABLERXDATA = 1;
  543. if (m_nfc_lib_callback != NULL)
  544. {
  545. m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0);
  546. }
  547. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  548. /* Begin: Bugfix for FTPAN-45 (IC-6915) */
  549. m_nfc_active = 0;
  550. /* End: Bugfix for FTPAN-45 (IC-6915) */
  551. #endif
  552. LOG_HAL_NFC("[NFC_HAL]: tx_fend\r\n");
  553. }
  554. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  555. /* Begin: Bugfix for FTPAN-45 (IC-6915) */
  556. if (NRF_NFCT->EVENTS_RXFRAMESTART)
  557. {
  558. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMESTART);
  559. if (m_nfc_active == 0)
  560. {
  561. m_nfc_active = 1;
  562. }
  563. LOG_HAL_NFC("[NFC_HAL]: rx_fstart\r\n");
  564. }
  565. if (NRF_NFCT->EVENTS_TXFRAMESTART)
  566. {
  567. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART);
  568. if (m_nfc_active == 0)
  569. {
  570. m_nfc_active = 1;
  571. }
  572. LOG_HAL_NFC("[NFC_HAL]: tx_fstart\r\n");
  573. }
  574. /* End: Bugfix for FTPAN-45 (IC-6915) */
  575. #endif
  576. if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk))
  577. {
  578. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED);
  579. /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */
  580. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
  581. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
  582. /* Set up registers for EasyDMA and start receiving packets */
  583. NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
  584. NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
  585. NRF_NFCT->TASKS_ENABLERXDATA = 1;
  586. NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) |
  587. (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos);
  588. /* At this point any previous error status can be ignored */
  589. NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
  590. NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
  591. #ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  592. /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */
  593. m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK;
  594. #endif
  595. if (m_nfc_lib_callback != NULL)
  596. {
  597. m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0);
  598. }
  599. LOG_HAL_NFC("[NFC_HAL]: selected\r\n");
  600. }
  601. if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk))
  602. {
  603. uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX;
  604. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
  605. LOG_HAL_NFC("[NFC_HAL]: rxerror (0x%x)\r\n", (unsigned int) rx_status);
  606. (void) rx_status;
  607. /* Clear rx frame status */
  608. NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
  609. }
  610. if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk))
  611. {
  612. uint32_t err_status = NRF_NFCT->ERRORSTATUS;
  613. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR);
  614. /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */
  615. if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received)
  616. {
  617. NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
  618. m_slp_req_received = false;
  619. LOG_HAL_NFC("[NFC_HAL]: error (SLP_REQ)\r\n");
  620. }
  621. /* Report any other error */
  622. err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
  623. if (err_status)
  624. {
  625. LOG_HAL_NFC("[NFC_HAL]: error (0x%x)\r\n", (unsigned int) err_status);
  626. }
  627. /* Clear error status */
  628. NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
  629. }
  630. HAL_NFC_DEBUG_PIN_CLEAR(NFC_EVENT_PIN); //DEBUG!
  631. }
  632. #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
  633. #ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND
  634. #error Wrong workaround combination
  635. #endif
  636. static uint32_t field_state_cnt = 0;
  637. /**
  638. * @brief Function for evaluating and handling NFC fieldlost event.
  639. */
  640. static void hal_nfc_field_check(void)
  641. {
  642. uint32_t nfc_fieldpresen_masked;
  643. nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK;
  644. if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST)
  645. {
  646. ++field_state_cnt;
  647. if (field_state_cnt > 7)
  648. {
  649. HAL_NFC_DEBUG_PIN_SET(HCLOCK_OFF_PIN); //DEBUG!
  650. NRF_TIMER4->TASKS_SHUTDOWN = 1;
  651. nrf_drv_clock_hfclk_release();
  652. /* Begin: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */
  653. // reset the NFC for release HFCLK
  654. __DMB();
  655. NRF_NFCT_POWER = 0;
  656. __DMB();
  657. NRF_NFCT_POWER = 1;
  658. /* END: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */
  659. if ((m_nfc_lib_callback != NULL) )
  660. {
  661. m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
  662. }
  663. m_field_on = false;
  664. /* Begin: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */
  665. // resume the NFCT to initialized state
  666. hal_nfc_re_setup();
  667. /* END: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */
  668. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); //DEBUG!
  669. }
  670. return;
  671. }
  672. field_state_cnt = 0;
  673. }
  674. /**
  675. * @brief Function for enablinge hight precision clock and start eveluating fieldlost event.
  676. */
  677. static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
  678. {
  679. if (!m_field_on)
  680. {
  681. HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG!
  682. nrf_drv_clock_hfclk_request(&m_clock_handler_item);
  683. NRF_TIMER4->TASKS_CLEAR = 1;
  684. NRF_TIMER4->TASKS_START = 1;
  685. field_state_cnt = 0;
  686. HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG!
  687. }
  688. m_field_on = true;
  689. }
  690. /**
  691. * @brief Function for resume the NFCT to initialized state after software's reset.
  692. */
  693. static inline void hal_nfc_re_setup(void)
  694. {
  695. uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR];
  696. hal_nfc_common_hw_setup(nfc_internal);
  697. LOG_HAL_NFC("[NFC_HAL]: reinitialize\r\n");
  698. }
  699. #endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND