nrfx_nfct.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /**
  2. * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include <nrfx.h>
  41. #if NRFX_CHECK(NRFX_NFCT_ENABLED)
  42. #include <nrfx_nfct.h>
  43. #define NRFX_LOG_MODULE NFCT
  44. #include <nrfx_log.h>
  45. #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB) || defined(NRF52840_XXAA)
  46. #define USE_TIMER_WORKAROUND
  47. #endif
  48. #ifdef USE_TIMER_WORKAROUND
  49. #include <nrfx_timer.h>
  50. typedef struct
  51. {
  52. const nrfx_timer_t timer; /**< Timer instance that supports the correct NFC field detection. */
  53. #ifdef NRF52840_XXAA
  54. bool fieldevents_filter_active; /**< Flag that indicates that the field events are ignored. */
  55. bool is_hfclk_on; /**< HFCLK has started - one of the NFC activation conditions. */
  56. bool is_delayed; /**< Required time delay has passed - one of the NFC activation conditions. */
  57. #else
  58. uint32_t field_state_cnt; /**< Counter of the FIELDLOST events. */
  59. #endif // NRF52840_XXAA
  60. } nrfx_nfct_timer_workaround_t;
  61. #ifdef NRF52840_XXAA
  62. #define NRFX_NFCT_ACTIVATE_DELAY 1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */
  63. #define NRFX_NFCT_TIMER_PERIOD NRFX_NFCT_ACTIVATE_DELAY
  64. #else
  65. #define NRFX_NFCT_FIELDLOST_THR 7
  66. #define NRFX_NFCT_FIELD_TIMER_PERIOD 100 /**< Field polling period in us. */
  67. #define NRFX_NFCT_TIMER_PERIOD NRFX_NFCT_FIELD_TIMER_PERIOD
  68. #endif // NRF52840_XXAA
  69. #define NRFX_NFCT_TIMER_INSTANCE 4 /**< Timer instance used for various workarounds for the NFCT HW issues.*/
  70. static nrfx_nfct_timer_workaround_t m_timer_workaround =
  71. {
  72. .timer = NRFX_TIMER_INSTANCE(NRFX_NFCT_TIMER_INSTANCE),
  73. };
  74. #endif // USE_TIMER_WORKAROUND
  75. #define NRFX_NFCT_FRAMEDELAYMAX_52840S (0xFFFFUL) /**< Bit mask of the FRAMEDELAYMAX field for the first sample of 52840.*/
  76. #define NRFX_NFCT_FWT_MAX_DIFF 1u /**< The maximal difference between the requested FWT and HW-limited FWT settings.*/
  77. /* Mask of all possible interrupts that are relevant for data reception. */
  78. #define NRFX_NFCT_RX_INT_MASK (NRF_NFCT_INT_RXFRAMESTART_MASK | \
  79. NRF_NFCT_INT_RXFRAMEEND_MASK | \
  80. NRF_NFCT_INT_RXERROR_MASK)
  81. /* Mask of all possible interrupts that are relevant for data transmission. */
  82. #define NRFX_NFCT_TX_INT_MASK (NRF_NFCT_INT_TXFRAMESTART_MASK | \
  83. NRF_NFCT_INT_TXFRAMEEND_MASK)
  84. /* Mask of all possible errors from the @ref NRF_NFCT_EVENT_RXERROR event. */
  85. #define NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK (NRF_NFCT_RX_FRAME_STATUS_CRC_MASK | \
  86. NRF_NFCT_RX_FRAME_STATUS_PARITY_MASK | \
  87. NRF_NFCT_RX_FRAME_STATUS_OVERRUN_MASK)
  88. /* Mask of all possible errors from the @ref NRF_NFCT_EVENT_ERROR event. */
  89. #if defined (NRF52832_XXAA) || defined(NRF52832_XXAB)
  90. #define NRFX_NFCT_ERROR_STATUS_ALL_MASK (NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK | \
  91. NRF_NFCT_ERROR_NFCFIELDTOOSTRONG_MASK | \
  92. NRF_NFCT_ERROR_NFCFIELDTOOWEAK_MASK)
  93. #else
  94. #define NRFX_NFCT_ERROR_STATUS_ALL_MASK (NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK)
  95. #endif
  96. /* Macros for conversion of bits to bytes. */
  97. #define NRFX_NFCT_BYTES_TO_BITS(_bytes) ((_bytes) << 3)
  98. #define NRFX_NFCT_BITS_TO_BYTES(_bits) ((_bits) >> 3)
  99. /* Macro for checking whether the NFCT interrupt is active. */
  100. #define NRFX_NFCT_EVT_ACTIVE(_name) (nrf_nfct_event_check(NRFX_CONCAT_2(NRF_NFCT_EVENT_, _name)) && \
  101. nrf_nfct_int_enable_check(NRFX_CONCAT_3(NRF_NFCT_INT_, _name, _MASK)))
  102. /* Macro for callback execution. */
  103. #define NRFX_NFCT_CB_HANDLE(_cb, _evt) \
  104. if (_cb != NULL) \
  105. { \
  106. _cb(&_evt); \
  107. }
  108. typedef enum
  109. {
  110. NRFX_NFC_FIELD_STATE_NONE, /**< Initial value that indicates no NFCT field events. */
  111. NRFX_NFC_FIELD_STATE_OFF, /**< The NFCT FIELDLOST event has been set. */
  112. NRFX_NFC_FIELD_STATE_ON, /**< The NFCT FIELDDETECTED event has been set. */
  113. NRFX_NFC_FIELD_STATE_UNKNOWN /**< Both NFCT field events have been set - ambiguous state. */
  114. } nrfx_nfct_field_state_t;
  115. #ifdef NRF52840_XXAA
  116. /**
  117. * @brief Internal auxiliary function for checking whether the program is running on the NRF52840 chip.
  118. *
  119. * @retval true It is NRF52480 chip.
  120. * @retval false It is an other chip.
  121. */
  122. static inline bool nrfx_nfct_type_52840_check(void)
  123. {
  124. return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
  125. (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
  126. }
  127. /**
  128. * @brief Internal auxiliary function for checking whether the program is running on the first sample of
  129. * the nRF52840 chip.
  130. *
  131. * @retval true It is the nRF52480 chip and it is the first sample version.
  132. * @retval false It is an other chip.
  133. */
  134. static inline bool nrfx_nfct_type_52840_sample_check(void)
  135. {
  136. return ( nrfx_nfct_type_52840_check() &&
  137. ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
  138. ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
  139. }
  140. /**
  141. * @brief Internal auxiliary function for checking whether the program is running on the final version of
  142. * the nRF52840 chip.
  143. *
  144. * @retval true It is the nRF52480 chip and it is the final version.
  145. * @retval false It is an other chip.
  146. */
  147. static inline bool nrfx_nfct_type_52840_final_check(void)
  148. {
  149. return ( nrfx_nfct_type_52840_check() &&
  150. ( ( ((*(uint32_t *)0xF0000FE8) & 0xF0) != 0x00 ) ||
  151. ( ((*(uint32_t *)0xF0000FEC) & 0xF0) != 0x00 ) ));
  152. }
  153. typedef struct
  154. {
  155. bool eng_a; /**< Engineering sample A of the NRF52840 chip. */
  156. bool eng_bc; /**< Engineering sample B, C of the NRF52840 chip, or its final version. */
  157. } nrfx_nfct_nrf52840_ver_t;
  158. static nrfx_nfct_nrf52840_ver_t m_nrf52840;
  159. #endif // NRF52840_XXAA
  160. /**@brief NFCT control block. */
  161. typedef struct
  162. {
  163. nrfx_nfct_config_t config;
  164. nrfx_drv_state_t state;
  165. volatile bool field_on;
  166. } nrfx_nfct_control_block_t;
  167. static nrfx_nfct_control_block_t m_nfct_cb;
  168. /**
  169. * @brief Common part of the setup used for the NFCT initialization and reinitialization.
  170. */
  171. static void nrfx_nfct_hw_init_setup(void)
  172. {
  173. #ifdef NRF52840_XXAA
  174. if (m_nrf52840.eng_a)
  175. {
  176. /* Begin: Bugfix for FTPAN-98 */
  177. *(volatile uint32_t *) 0x4000568C = 0x00038148;
  178. /* End: Bugfix for FTPAN-98 */
  179. /* Begin: Bugfix for FTPAN-144 */
  180. *(volatile uint32_t *) 0x4000561c = 0x01;
  181. *(volatile uint32_t *) 0x4000562c = 0x3F;
  182. *(volatile uint32_t *) 0x4000563c = 0x0;
  183. /* End: Bugfix for FTPAN-144 */
  184. }
  185. #endif // NRF52840_XXAA
  186. // Use Window Grid frame delay mode.
  187. nrf_nfct_frame_delay_mode_set(NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID);
  188. /* Begin: Bugfix for FTPAN-25 (IC-9929) */
  189. /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
  190. because it is required to operate with Windows Phone */
  191. nrf_nfct_sensres_bit_frame_sdd_set(NRF_NFCT_SENSRES_BIT_FRAME_SDD_00100);
  192. /* End: Bugfix for FTPAN-25 (IC-9929) */
  193. }
  194. /**@brief Function for evaluating and handling the NFC field events.
  195. *
  196. * @param[in] field_state Current field state.
  197. */
  198. static void nrfx_nfct_field_event_handler(volatile nrfx_nfct_field_state_t field_state)
  199. {
  200. nrfx_nfct_evt_t nfct_evt;
  201. #ifdef NRF52840_XXAA
  202. if((!m_nrf52840.eng_a) && (m_timer_workaround.fieldevents_filter_active))
  203. {
  204. return;
  205. }
  206. #endif // NRF52840_XXAA
  207. if (field_state == NRFX_NFC_FIELD_STATE_UNKNOWN)
  208. {
  209. /* Probe NFC field */
  210. field_state = (nrfx_nfct_field_check()) ? NRFX_NFC_FIELD_STATE_ON : NRFX_NFC_FIELD_STATE_OFF;
  211. }
  212. /* Field event service */
  213. switch (field_state)
  214. {
  215. case NRFX_NFC_FIELD_STATE_ON:
  216. if (!m_nfct_cb.field_on)
  217. {
  218. #ifdef NRF52840_XXAA
  219. /* Begin: Bugfix for FTPAN-190 */
  220. if (!m_nrf52840.eng_a)
  221. {
  222. m_timer_workaround.is_hfclk_on = false;
  223. m_timer_workaround.is_delayed = false;
  224. m_timer_workaround.fieldevents_filter_active = true;
  225. nrfx_timer_clear(&m_timer_workaround.timer);
  226. nrfx_timer_enable(&m_timer_workaround.timer);
  227. }
  228. /* END: Bugfix for FTPAN-190 */
  229. #elif defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  230. nrfx_timer_clear(&m_timer_workaround.timer);
  231. nrfx_timer_enable(&m_timer_workaround.timer);
  232. m_timer_workaround.field_state_cnt = 0;
  233. #endif // NRF52840_XXAA
  234. m_nfct_cb.field_on = true;
  235. nfct_evt.evt_id = NRFX_NFCT_EVT_FIELD_DETECTED;
  236. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  237. }
  238. break;
  239. case NRFX_NFC_FIELD_STATE_OFF:
  240. nrfx_nfct_state_force(NRFX_NFCT_STATE_SENSING);
  241. #ifdef NRF52840_XXAA
  242. /* Begin: Bugfix for FTPAN-116 (IC-12886) */
  243. if (m_nrf52840.eng_a)
  244. {
  245. *(volatile uint32_t *)0x40005010 = 1;
  246. }
  247. /* END: Bugfix for FTPAN-116 (IC-12886) */
  248. #endif // NRF52840_XXAA
  249. nrf_nfct_int_disable(NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
  250. m_nfct_cb.field_on = false;
  251. nfct_evt.evt_id = NRFX_NFCT_EVT_FIELD_LOST;
  252. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  253. break;
  254. default:
  255. /* No implementation required */
  256. break;
  257. }
  258. }
  259. #ifdef USE_TIMER_WORKAROUND
  260. #ifdef NRF52840_XXAA
  261. static void nrfx_nfct_activate_check(void)
  262. {
  263. static bool is_field_validation_pending = false;
  264. if (is_field_validation_pending)
  265. {
  266. is_field_validation_pending = false;
  267. m_timer_workaround.fieldevents_filter_active = false;
  268. // Check the field status and take action if field is lost.
  269. nrfx_nfct_field_event_handler(NRFX_NFC_FIELD_STATE_UNKNOWN);
  270. return;
  271. }
  272. if ((m_timer_workaround.is_hfclk_on) && (m_timer_workaround.is_delayed))
  273. {
  274. nrf_nfct_task_trigger(NRF_NFCT_TASK_ACTIVATE);
  275. is_field_validation_pending = true;
  276. // Start the timer second time to validate whether the tag has locked to the field.
  277. nrfx_timer_clear(&m_timer_workaround.timer);
  278. nrfx_timer_enable(&m_timer_workaround.timer);
  279. }
  280. }
  281. #endif // NRF52840_XXAA
  282. #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  283. static inline void nrfx_nfct_reset(void)
  284. {
  285. uint32_t fdm;
  286. uint32_t int_enabled;
  287. uint8_t nfcid1[NRF_NFCT_SENSRES_NFCID1_SIZE_TRIPLE];
  288. nrf_nfct_sensres_nfcid1_size_t nfcid1_size;
  289. nrf_nfct_selres_protocol_t protocol;
  290. // Save parameter settings before the reset of the NFCT peripheral.
  291. fdm = nrf_nfct_frame_delay_max_get();
  292. nfcid1_size = nrf_nfct_nfcid1_get(nfcid1);
  293. protocol = nrf_nfct_selsres_protocol_get();
  294. int_enabled = nrf_nfct_int_enable_get();
  295. // Reset the NFCT peripheral.
  296. *(volatile uint32_t *)0x40005FFC = 0;
  297. *(volatile uint32_t *)0x40005FFC;
  298. *(volatile uint32_t *)0x40005FFC = 1;
  299. // Restore parameter settings after the reset of the NFCT peripheral.
  300. nrf_nfct_frame_delay_max_set(fdm);
  301. nrf_nfct_nfcid1_set(nfcid1, nfcid1_size);
  302. nrf_nfct_selres_protocol_set(protocol);
  303. // Restore general HW configuration.
  304. nrfx_nfct_hw_init_setup();
  305. // Restore interrupts.
  306. nrf_nfct_int_enable(int_enabled);
  307. // Disable interrupts associated with data exchange.
  308. nrf_nfct_int_disable(NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
  309. NRFX_LOG_INFO("Reinitialize");
  310. }
  311. static void nrfx_nfct_field_poll(void)
  312. {
  313. if (!nrfx_nfct_field_check())
  314. {
  315. if (++m_timer_workaround.field_state_cnt > NRFX_NFCT_FIELDLOST_THR)
  316. {
  317. nrfx_nfct_evt_t nfct_evt =
  318. {
  319. .evt_id = NRFX_NFCT_EVT_FIELD_LOST,
  320. };
  321. nrfx_timer_disable(&m_timer_workaround.timer);
  322. m_nfct_cb.field_on = false;
  323. /* Begin: Bugfix for FTPAN-116 */
  324. // resume the NFCT to initialized state
  325. nrfx_nfct_reset();
  326. /* End: Bugfix for FTPAN-116 */
  327. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  328. }
  329. return;
  330. }
  331. m_timer_workaround.field_state_cnt = 0;
  332. }
  333. #endif // defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  334. static void nrfx_nfct_field_timer_handler(nrf_timer_event_t event_type, void * p_context)
  335. {
  336. (void)p_context;
  337. if (event_type != NRF_TIMER_EVENT_COMPARE0)
  338. {
  339. return;
  340. }
  341. #ifdef NRF52840_XXAA
  342. m_timer_workaround.is_delayed = true;
  343. nrfx_timer_disable(&m_timer_workaround.timer);
  344. nrfx_nfct_activate_check();
  345. #else
  346. nrfx_nfct_field_poll();
  347. #endif //NRF52840_XXAA
  348. }
  349. static inline nrfx_err_t nrfx_nfct_field_timer_config(void)
  350. {
  351. nrfx_err_t err_code;
  352. nrfx_timer_config_t timer_cfg =
  353. {
  354. .frequency = NRF_TIMER_FREQ_1MHz,
  355. .mode = NRF_TIMER_MODE_TIMER,
  356. .bit_width = NRF_TIMER_BIT_WIDTH_16,
  357. .interrupt_priority = NRFX_NFCT_CONFIG_IRQ_PRIORITY
  358. };
  359. err_code = nrfx_timer_init(&m_timer_workaround.timer, &timer_cfg, nrfx_nfct_field_timer_handler);
  360. if (err_code != NRFX_SUCCESS)
  361. {
  362. return err_code;
  363. }
  364. nrfx_timer_extended_compare(&m_timer_workaround.timer,
  365. NRF_TIMER_CC_CHANNEL0,
  366. nrfx_timer_us_to_ticks(&m_timer_workaround.timer, NRFX_NFCT_TIMER_PERIOD),
  367. NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
  368. true);
  369. return err_code;
  370. }
  371. #endif // USE_TIMER_WORKAROUND
  372. static inline nrf_nfct_sensres_nfcid1_size_t nrf_nfct_nfcid1_size_to_sensres_size(uint8_t nfcid1_size)
  373. {
  374. switch (nfcid1_size)
  375. {
  376. case NRFX_NFCT_NFCID1_SINGLE_SIZE:
  377. return NRF_NFCT_SENSRES_NFCID1_SIZE_SINGLE;
  378. case NRFX_NFCT_NFCID1_DOUBLE_SIZE:
  379. return NRF_NFCT_SENSRES_NFCID1_SIZE_DOUBLE;
  380. case NRFX_NFCT_NFCID1_TRIPLE_SIZE:
  381. return NRF_NFCT_SENSRES_NFCID1_SIZE_TRIPLE;
  382. default:
  383. return NRF_NFCT_SENSRES_NFCID1_SIZE_DOUBLE;
  384. }
  385. }
  386. static inline void nrfx_nfct_rxtx_int_enable(uint32_t rxtx_int_mask)
  387. {
  388. nrf_nfct_int_enable(rxtx_int_mask & m_nfct_cb.config.rxtx_int_mask);
  389. }
  390. nrfx_err_t nrfx_nfct_init(nrfx_nfct_config_t const * p_config)
  391. {
  392. NRFX_ASSERT(p_config);
  393. nrfx_err_t err_code = NRFX_SUCCESS;
  394. if (m_nfct_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
  395. {
  396. return NRFX_ERROR_INVALID_STATE;
  397. }
  398. #ifdef NRF52840_XXAA
  399. m_nrf52840.eng_a = nrfx_nfct_type_52840_sample_check();
  400. m_nrf52840.eng_bc = nrfx_nfct_type_52840_final_check();
  401. #endif // NRF52840_XXAA
  402. m_nfct_cb.config = *p_config;
  403. nrfx_nfct_hw_init_setup();
  404. NRFX_IRQ_PENDING_CLEAR(NFCT_IRQn);
  405. NRFX_IRQ_PRIORITY_SET(NFCT_IRQn, NRFX_NFCT_CONFIG_IRQ_PRIORITY);
  406. NRFX_IRQ_ENABLE(NFCT_IRQn);
  407. #ifdef USE_TIMER_WORKAROUND
  408. /* Initialize Timer module as the workaround for NFCT HW issues. */
  409. #ifdef NRF52840_XXAA
  410. if (!m_nrf52840.eng_a)
  411. #endif // NRF52840_XXAA
  412. {
  413. err_code = nrfx_nfct_field_timer_config();
  414. }
  415. #endif // USE_TIMER_WORKAROUND
  416. if (err_code == NRFX_SUCCESS)
  417. {
  418. uint8_t default_nfcid1[NRFX_NFCT_NFCID1_DEFAULT_LEN];
  419. err_code = nrfx_nfct_nfcid1_default_bytes_get(default_nfcid1, sizeof(default_nfcid1));
  420. NRFX_ASSERT(err_code == NRFX_SUCCESS);
  421. nrf_nfct_nfcid1_set(default_nfcid1, NRF_NFCT_SENSRES_NFCID1_SIZE_DEFAULT);
  422. }
  423. else
  424. {
  425. return err_code;
  426. }
  427. m_nfct_cb.state = NRFX_DRV_STATE_INITIALIZED;
  428. NRFX_LOG_INFO("Initialized");
  429. return err_code;
  430. }
  431. void nrfx_nfct_uninit(void)
  432. {
  433. nrfx_nfct_disable();
  434. NRFX_IRQ_DISABLE(NFCT_IRQn);
  435. NRFX_IRQ_PENDING_CLEAR(NFCT_IRQn);
  436. #ifdef USE_TIMER_WORKAROUND
  437. /* Initialize Timer module as the workaround for NFCT HW issues. */
  438. #ifdef NRF52840_XXAA
  439. if (!m_nrf52840.eng_a)
  440. #endif // NRF52840_XXAA
  441. {
  442. nrfx_timer_uninit(&m_timer_workaround.timer);
  443. }
  444. #endif // USE_TIMER_WORKAROUND
  445. m_nfct_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
  446. }
  447. void nrfx_nfct_enable(void)
  448. {
  449. nrf_nfct_error_status_clear(NRFX_NFCT_ERROR_STATUS_ALL_MASK);
  450. nrf_nfct_task_trigger(NRF_NFCT_TASK_SENSE);
  451. nrf_nfct_int_enable(NRF_NFCT_INT_FIELDDETECTED_MASK | NRF_NFCT_INT_ERROR_MASK |
  452. NRF_NFCT_INT_SELECTED_MASK);
  453. #if !defined(NRF52832_XXAA) && !defined(NRF52832_XXAB)
  454. nrf_nfct_int_enable(NRF_NFCT_INT_FIELDLOST_MASK);
  455. #endif //!defined(NRF52832_XXAA) && !defined(NRF52832_XXAB)
  456. NRFX_LOG_INFO("Start");
  457. }
  458. void nrfx_nfct_disable(void)
  459. {
  460. nrf_nfct_int_disable(NRF_NFCT_DISABLE_ALL_INT);
  461. nrf_nfct_task_trigger(NRF_NFCT_TASK_DISABLE);
  462. NRFX_LOG_INFO("Stop");
  463. }
  464. bool nrfx_nfct_field_check(void)
  465. {
  466. uint32_t const field_state = nrf_nfct_field_status_get();
  467. if (((field_state & NRF_NFCT_FIELD_STATE_PRESENT_MASK) == 0) &&
  468. ((field_state & NRF_NFCT_FIELD_STATE_LOCK_MASK) == 0))
  469. {
  470. // Field is not active
  471. return false;
  472. }
  473. return true;
  474. }
  475. void nrfx_nfct_rx(nrfx_nfct_data_desc_t const * p_tx_data)
  476. {
  477. NRFX_ASSERT(p_tx_data);
  478. nrf_nfct_rxtx_buffer_set((uint8_t *) p_tx_data->p_data, p_tx_data->data_size);
  479. nrfx_nfct_rxtx_int_enable(NRFX_NFCT_RX_INT_MASK);
  480. nrf_nfct_task_trigger(NRF_NFCT_TASK_ENABLERXDATA);
  481. }
  482. nrfx_err_t nrfx_nfct_tx(nrfx_nfct_data_desc_t const * p_tx_data,
  483. nrf_nfct_frame_delay_mode_t delay_mode)
  484. {
  485. NRFX_ASSERT(p_tx_data);
  486. NRFX_ASSERT(p_tx_data->p_data);
  487. if (p_tx_data->data_size == 0)
  488. {
  489. return NRFX_ERROR_INVALID_LENGTH;
  490. }
  491. nrf_nfct_rxtx_buffer_set((uint8_t *) p_tx_data->p_data, p_tx_data->data_size);
  492. nrf_nfct_tx_bits_set(NRFX_NFCT_BYTES_TO_BITS(p_tx_data->data_size));
  493. nrf_nfct_frame_delay_mode_set((nrf_nfct_frame_delay_mode_t) delay_mode);
  494. nrfx_nfct_rxtx_int_enable(NRFX_NFCT_TX_INT_MASK);
  495. nrf_nfct_task_trigger(NRF_NFCT_TASK_STARTTX);
  496. NRFX_LOG_INFO("Tx start");
  497. return NRFX_SUCCESS;
  498. }
  499. void nrfx_nfct_state_force(nrfx_nfct_state_t state)
  500. {
  501. #ifdef NRF52840_XXAA
  502. if ((m_nrf52840.eng_bc) && (state == NRFX_NFCT_STATE_ACTIVATED))
  503. {
  504. m_timer_workaround.is_hfclk_on = true;
  505. nrfx_nfct_activate_check();
  506. }
  507. #endif
  508. {
  509. nrf_nfct_task_trigger((nrf_nfct_task_t) state);
  510. }
  511. }
  512. void nrfx_nfct_init_substate_force(nrfx_nfct_active_state_t sub_state)
  513. {
  514. if (sub_state == NRFX_NFCT_ACTIVE_STATE_DEFAULT)
  515. {
  516. #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  517. if (((*(uint32_t volatile *)(0x40005420)) & 0x1UL) == (1UL))
  518. #else
  519. if (nrf_nfct_sleep_state_get() == NRF_NFCT_SLEEP_STATE_SLEEP_A)
  520. #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  521. {
  522. // Default state is SLEEP_A
  523. nrf_nfct_task_trigger(NRF_NFCT_TASK_GOSLEEP);
  524. }
  525. else
  526. {
  527. // Default state is IDLE
  528. nrf_nfct_task_trigger(NRF_NFCT_TASK_GOIDLE);
  529. }
  530. }
  531. else
  532. {
  533. nrf_nfct_task_trigger((nrf_nfct_task_t) sub_state);
  534. }
  535. /* Disable TX/RX here (will be enabled at SELECTED) */
  536. nrf_nfct_int_disable(NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
  537. }
  538. nrfx_err_t nrfx_nfct_parameter_set(nrfx_nfct_param_t const * p_param)
  539. {
  540. NRFX_ASSERT(p_param);
  541. switch (p_param->id)
  542. {
  543. case NRFX_NFCT_PARAM_ID_FDT:
  544. {
  545. uint32_t delay = p_param->data.fdt;
  546. uint32_t delay_thr = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk;
  547. #ifdef NRF52840_XXAA
  548. delay_thr = (m_nrf52840.eng_a) ? NRFX_NFCT_FRAMEDELAYMAX_52840S : delay_thr;
  549. #endif // NRF52840_XXAA
  550. // Delay validation.
  551. if (delay > (delay_thr + NRFX_NFCT_FWT_MAX_DIFF))
  552. {
  553. return NRFX_ERROR_INVALID_PARAM;
  554. }
  555. delay = (delay > delay_thr) ? delay_thr : delay;
  556. nrf_nfct_frame_delay_max_set(delay);
  557. break;
  558. }
  559. case NRFX_NFCT_PARAM_ID_SEL_RES:
  560. if (p_param->data.sel_res_protocol > NRF_NFCT_SELRES_PROTOCOL_NFCDEP_T4AT)
  561. {
  562. return NRFX_ERROR_INVALID_PARAM;
  563. }
  564. nrf_nfct_selres_protocol_set((nrf_nfct_selres_protocol_t) p_param->data.sel_res_protocol);
  565. break;
  566. case NRFX_NFCT_PARAM_ID_NFCID1:
  567. {
  568. nrf_nfct_sensres_nfcid1_size_t id_size_mask;
  569. id_size_mask = nrf_nfct_nfcid1_size_to_sensres_size(p_param->data.nfcid1.id_size);
  570. nrf_nfct_nfcid1_set(p_param->data.nfcid1.p_id, id_size_mask);
  571. break;
  572. }
  573. default:
  574. break;
  575. }
  576. return NRFX_SUCCESS;
  577. }
  578. nrfx_err_t nrfx_nfct_nfcid1_default_bytes_get(uint8_t * const p_nfcid1_buff,
  579. uint32_t nfcid1_buff_len)
  580. {
  581. if ((nfcid1_buff_len != NRFX_NFCT_NFCID1_SINGLE_SIZE) &&
  582. (nfcid1_buff_len != NRFX_NFCT_NFCID1_DOUBLE_SIZE) &&
  583. (nfcid1_buff_len != NRFX_NFCT_NFCID1_TRIPLE_SIZE))
  584. {
  585. return NRFX_ERROR_INVALID_LENGTH;
  586. }
  587. uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0;
  588. uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1;
  589. uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2;
  590. p_nfcid1_buff[0] = (uint8_t) (nfc_tag_header0 >> 0);
  591. p_nfcid1_buff[1] = (uint8_t) (nfc_tag_header0 >> 8);
  592. p_nfcid1_buff[2] = (uint8_t) (nfc_tag_header0 >> 16);
  593. p_nfcid1_buff[3] = (uint8_t) (nfc_tag_header1 >> 0);
  594. if (nfcid1_buff_len != NRFX_NFCT_NFCID1_SINGLE_SIZE)
  595. {
  596. p_nfcid1_buff[4] = (uint8_t) (nfc_tag_header1 >> 8);
  597. p_nfcid1_buff[5] = (uint8_t) (nfc_tag_header1 >> 16);
  598. p_nfcid1_buff[6] = (uint8_t) (nfc_tag_header1 >> 24);
  599. if (nfcid1_buff_len == NRFX_NFCT_NFCID1_TRIPLE_SIZE)
  600. {
  601. p_nfcid1_buff[7] = (uint8_t) (nfc_tag_header2 >> 0);
  602. p_nfcid1_buff[8] = (uint8_t) (nfc_tag_header2 >> 8);
  603. p_nfcid1_buff[9] = (uint8_t) (nfc_tag_header2 >> 16);
  604. }
  605. /* Begin: Bugfix for FTPAN-181. */
  606. /* Workaround for wrong value in NFCID1. Value 0x88 cannot be used as byte 3
  607. of a double-size NFCID1, according to the NFC Forum Digital Protocol specification. */
  608. else if (p_nfcid1_buff[3] == 0x88)
  609. {
  610. p_nfcid1_buff[3] |= 0x11;
  611. }
  612. /* End: Bugfix for FTPAN-181 */
  613. }
  614. return NRFX_SUCCESS;
  615. }
  616. void nrfx_nfct_autocolres_enable(void)
  617. {
  618. #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  619. (*(uint32_t *)(0x4000559C)) &= (~(0x1UL));
  620. #else
  621. nrf_nfct_autocolres_enable();
  622. #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  623. }
  624. void nrfx_nfct_autocolres_disable(void)
  625. {
  626. #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  627. (*(uint32_t *)(0x4000559C)) |= (0x1UL);
  628. #else
  629. nrf_nfct_autocolres_disable();
  630. #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
  631. }
  632. void nrfx_nfct_irq_handler(void)
  633. {
  634. nrfx_nfct_field_state_t current_field = NRFX_NFC_FIELD_STATE_NONE;
  635. if (NRFX_NFCT_EVT_ACTIVE(FIELDDETECTED))
  636. {
  637. nrf_nfct_event_clear(NRF_NFCT_EVENT_FIELDDETECTED);
  638. current_field = NRFX_NFC_FIELD_STATE_ON;
  639. NRFX_LOG_DEBUG("Field detected");
  640. }
  641. #if !defined(NRF52832_XXAA) && !defined(NRF52832_XXAB)
  642. if (NRFX_NFCT_EVT_ACTIVE(FIELDLOST))
  643. {
  644. nrf_nfct_event_clear(NRF_NFCT_EVENT_FIELDLOST);
  645. current_field = (current_field == NRFX_NFC_FIELD_STATE_NONE) ?
  646. NRFX_NFC_FIELD_STATE_OFF : NRFX_NFC_FIELD_STATE_UNKNOWN;
  647. NRFX_LOG_DEBUG("Field lost");
  648. }
  649. #endif //!defined(NRF52832_XXAA) && !defined(NRF52832_XXAB)
  650. /* Perform actions if any FIELD event is active */
  651. if (current_field != NRFX_NFC_FIELD_STATE_NONE)
  652. {
  653. nrfx_nfct_field_event_handler(current_field);
  654. }
  655. if (NRFX_NFCT_EVT_ACTIVE(RXFRAMEEND))
  656. {
  657. nrf_nfct_event_clear(NRF_NFCT_EVENT_RXFRAMEEND);
  658. nrfx_nfct_evt_t nfct_evt =
  659. {
  660. .evt_id = NRFX_NFCT_EVT_RX_FRAMEEND
  661. };
  662. /* Take into account only the number of whole bytes. */
  663. nfct_evt.params.rx_frameend.rx_status = 0;
  664. nfct_evt.params.rx_frameend.rx_data.p_data = nrf_nfct_rxtx_buffer_get();
  665. nfct_evt.params.rx_frameend.rx_data.data_size = NRFX_NFCT_BITS_TO_BYTES(nrf_nfct_rx_bits_get(true));
  666. if (NRFX_NFCT_EVT_ACTIVE(RXERROR))
  667. {
  668. nfct_evt.params.rx_frameend.rx_status =
  669. (nrf_nfct_rx_frame_status_get() & NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
  670. nrf_nfct_event_clear(NRF_NFCT_EVENT_RXERROR);
  671. NRFX_LOG_DEBUG("Rx error (0x%x)", (unsigned int) nfct_evt.params.rx_frameend.rx_status);
  672. /* Clear rx frame status */
  673. nrf_nfct_rx_frame_status_clear(NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
  674. }
  675. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  676. /* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */
  677. nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMESTART);
  678. NRFX_LOG_DEBUG("Rx fend");
  679. }
  680. if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
  681. {
  682. nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
  683. nrfx_nfct_evt_t nfct_evt =
  684. {
  685. .evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
  686. };
  687. /* Disable TX END event to ignore frame transmission other than READ response */
  688. nrf_nfct_int_disable(NRFX_NFCT_TX_INT_MASK);
  689. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  690. NRFX_LOG_DEBUG("Tx fend");
  691. }
  692. if (NRFX_NFCT_EVT_ACTIVE(SELECTED))
  693. {
  694. nrf_nfct_event_clear(NRF_NFCT_EVENT_SELECTED);
  695. /* Clear also RX END and RXERROR events because SW does not take care of
  696. commands that were received before selecting the tag. */
  697. nrf_nfct_event_clear(NRF_NFCT_EVENT_RXFRAMEEND);
  698. nrf_nfct_event_clear(NRF_NFCT_EVENT_RXERROR);
  699. nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMESTART);
  700. nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
  701. /* At this point any previous error status can be ignored. */
  702. nrf_nfct_rx_frame_status_clear(NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
  703. nrf_nfct_error_status_clear(NRFX_NFCT_ERROR_STATUS_ALL_MASK);
  704. nrfx_nfct_evt_t nfct_evt =
  705. {
  706. .evt_id = NRFX_NFCT_EVT_SELECTED
  707. };
  708. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  709. NRFX_LOG_DEBUG("Selected");
  710. }
  711. if (NRFX_NFCT_EVT_ACTIVE(ERROR))
  712. {
  713. uint32_t err_status = nrf_nfct_error_status_get();
  714. nrf_nfct_event_clear(NRF_NFCT_EVENT_ERROR);
  715. nrfx_nfct_evt_t nfct_evt =
  716. {
  717. .evt_id = NRFX_NFCT_EVT_ERROR
  718. };
  719. /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received. */
  720. if (err_status & NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK)
  721. {
  722. nrf_nfct_error_status_clear(NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK);
  723. nfct_evt.params.error.reason = NRFX_NFCT_ERROR_FRAMEDELAYTIMEOUT;
  724. NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
  725. }
  726. /* Report any other error. */
  727. err_status &= ~NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK;
  728. if (err_status)
  729. {
  730. NRFX_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status);
  731. }
  732. /* Clear error status. */
  733. nrf_nfct_error_status_clear(NRFX_NFCT_ERROR_STATUS_ALL_MASK);
  734. }
  735. if (NRFX_NFCT_EVT_ACTIVE(TXFRAMESTART))
  736. {
  737. nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMESTART);
  738. if (m_nfct_cb.config.cb != NULL)
  739. {
  740. nrfx_nfct_evt_t nfct_evt;
  741. nfct_evt.evt_id = NRFX_NFCT_EVT_TX_FRAMESTART;
  742. nfct_evt.params.tx_framestart.tx_data.p_data = nrf_nfct_rxtx_buffer_get();
  743. nfct_evt.params.tx_framestart.tx_data.data_size = NRFX_NFCT_BITS_TO_BYTES(nrf_nfct_tx_bits_get());
  744. m_nfct_cb.config.cb(&nfct_evt);
  745. }
  746. }
  747. }
  748. #endif // NRFX_CHECK(NRFX_NFCT_ENABLED)