1 /*
2  * Copyright (c) 2018 - 2023, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <nrfx.h>
35 
36 #if NRFX_CHECK(NRFX_NFCT_ENABLED)
37 
38 #include <nrfx_nfct.h>
39 
40 #define NRFX_LOG_MODULE NFCT
41 #include <nrfx_log.h>
42 
43 #define FIELD_TIMER_FREQUENCY_HZ NRFX_MHZ_TO_HZ(1)
44 
45 #if !defined(USE_WORKAROUND_FOR_ANOMALY_79) &&          \
46     (defined(NRF52832_XXAA) || defined(NRF52832_XXAB))
47 #define USE_WORKAROUND_FOR_ANOMALY_79 1
48 #endif
49 
50 #if !defined(USE_WORKAROUND_FOR_ANOMALY_190) &&          \
51     (defined(NRF52833_XXAA) || defined(NRF52840_XXAA) || \
52      defined(NRF5340_XXAA_APPLICATION))
53 #define USE_WORKAROUND_FOR_ANOMALY_190 1
54 #endif
55 
56 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79) || NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
57 #define NFCT_WORKAROUND_USES_TIMER 1
58 #endif
59 
60 #if NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
61 #include <nrfx_timer.h>
62 
63 typedef struct
64 {
65     const nrfx_timer_t timer;                     /**< Timer instance that supports the correct NFC field detection. */
66 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
67     bool               fieldevents_filter_active; /**< Flag that indicates that the field events are ignored. */
68     bool               is_hfclk_on;               /**< HFCLK has started - one of the NFC activation conditions. */
69     bool               is_delayed;                /**< Required time delay has passed - one of the NFC activation conditions. */
70 #elif NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
71     uint32_t           field_state_cnt;           /**< Counter of the FIELDLOST events. */
72 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
73 } nrfx_nfct_timer_workaround_t;
74 
75 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
76     #define NRFX_NFCT_ACTIVATE_DELAY     1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */
77     #define NRFX_NFCT_TIMER_PERIOD       NRFX_NFCT_ACTIVATE_DELAY
78 #elif NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
79     #define NRFX_NFCT_FIELDLOST_THR      7
80     #define NRFX_NFCT_FIELD_TIMER_PERIOD 100  /**< Field polling period in us. */
81     #define NRFX_NFCT_TIMER_PERIOD       NRFX_NFCT_FIELD_TIMER_PERIOD
82 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
83 
84 static nrfx_nfct_timer_workaround_t m_timer_workaround =
85 {
86     .timer = NRFX_TIMER_INSTANCE(NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID),
87 };
88 #endif // NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
89 
90 #define NFCT_FRAMEDELAYMAX_DEFAULT     (0x00001000UL) /**< Default value of the FRAMEDELAYMAX. */
91 #define NFCT_FRAMEDELAYMIN_DEFAULT     (0x00000480UL) /**< Default value of the FRAMEDELAYMIN. */
92 
93 /* Mask of all possible interrupts that are relevant for data reception. */
94 #define NRFX_NFCT_RX_INT_MASK (NRF_NFCT_INT_RXFRAMESTART_MASK | \
95                                NRF_NFCT_INT_RXFRAMEEND_MASK   | \
96                                NRF_NFCT_INT_RXERROR_MASK)
97 
98 /* Mask of all possible interrupts that are relevant for data transmission. */
99 #define NRFX_NFCT_TX_INT_MASK (NRF_NFCT_INT_TXFRAMESTART_MASK | \
100                                NRF_NFCT_INT_TXFRAMEEND_MASK)
101 
102 
103 /* Mask of all possible errors from the @ref NRF_NFCT_EVENT_RXERROR event. */
104 #define NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK (NRF_NFCT_RX_FRAME_STATUS_CRC_MASK    | \
105                                             NRF_NFCT_RX_FRAME_STATUS_PARITY_MASK | \
106                                             NRF_NFCT_RX_FRAME_STATUS_OVERRUN_MASK)
107 
108 /* Mask of all possible errors from the @ref NRF_NFCT_EVENT_ERROR event. */
109 #if defined (NRF52832_XXAA) || defined(NRF52832_XXAB)
110 #define NRFX_NFCT_ERROR_STATUS_ALL_MASK (NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK | \
111                                          NRF_NFCT_ERROR_NFCFIELDTOOSTRONG_MASK | \
112                                          NRF_NFCT_ERROR_NFCFIELDTOOWEAK_MASK)
113 #else
114 #define NRFX_NFCT_ERROR_STATUS_ALL_MASK (NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK)
115 #endif
116 
117 /* Macros for conversion of bits to bytes. */
118 #define NRFX_NFCT_BYTES_TO_BITS(_bytes) ((_bytes) << 3)
119 #define NRFX_NFCT_BITS_TO_BYTES(_bits)  ((_bits)  >> 3)
120 
121 /* Macro for checking whether the NFCT interrupt is active. */
122 #define NRFX_NFCT_EVT_ACTIVE(_name) \
123     (nrf_nfct_event_check(NRF_NFCT, NRFX_CONCAT_2(NRF_NFCT_EVENT_, _name)) && \
124      nrf_nfct_int_enable_check(NRF_NFCT, NRFX_CONCAT_3(NRF_NFCT_INT_, _name, _MASK)))
125 
126 /* Macro for callback execution. */
127 #define NRFX_NFCT_CB_HANDLE(_cb, _evt) \
128     if (_cb != NULL)                   \
129     {                                  \
130         _cb(&_evt);                    \
131     }
132 
133 typedef enum
134 {
135     NRFX_NFC_FIELD_STATE_NONE,   /**< Initial value that indicates no NFCT field events. */
136     NRFX_NFC_FIELD_STATE_OFF,    /**< The NFCT FIELDLOST event has been set. */
137     NRFX_NFC_FIELD_STATE_ON,     /**< The NFCT FIELDDETECTED event has been set. */
138     NRFX_NFC_FIELD_STATE_UNKNOWN /**< Both NFCT field events have been set - ambiguous state. */
139 } nrfx_nfct_field_state_t;
140 
141 /** @brief NFCT control block. */
142 typedef struct
143 {
144     nrfx_nfct_config_t config;
145     nrfx_drv_state_t   state;
146     volatile bool      field_on;
147     uint32_t           frame_delay_max;
148     uint32_t           frame_delay_min;
149 } nrfx_nfct_control_block_t;
150 
151 static nrfx_nfct_control_block_t m_nfct_cb;
152 
153 /**
154  * @brief Common part of the setup used for the NFCT initialization and reinitialization.
155  */
nrfx_nfct_hw_init_setup(void)156 static void nrfx_nfct_hw_init_setup(void)
157 {
158     // Use Window Grid frame delay mode.
159     nrf_nfct_frame_delay_mode_set(NRF_NFCT, NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID);
160 
161     /* Begin: Workaround for anomaly 25 */
162     /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
163        because it is required to operate with Windows Phone */
164     nrf_nfct_sensres_bit_frame_sdd_set(NRF_NFCT, NRF_NFCT_SENSRES_BIT_FRAME_SDD_00100);
165     /* End: Workaround for anomaly 25 */
166 }
167 
nrfx_nfct_frame_delay_max_set(bool default_delay)168 static void nrfx_nfct_frame_delay_max_set(bool default_delay)
169 {
170     if (default_delay)
171     {
172         nrf_nfct_frame_delay_max_set(NRF_NFCT, NFCT_FRAMEDELAYMAX_DEFAULT);
173     }
174     else
175     {
176         nrf_nfct_frame_delay_max_set(NRF_NFCT, m_nfct_cb.frame_delay_max);
177     }
178 }
179 
180 /** @brief Function for evaluating and handling the NFC field events.
181  *
182  * @param[in]  field_state  Current field state.
183  */
nrfx_nfct_field_event_handler(volatile nrfx_nfct_field_state_t field_state)184 static void nrfx_nfct_field_event_handler(volatile nrfx_nfct_field_state_t field_state)
185 {
186     nrfx_nfct_evt_t nfct_evt;
187 
188 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
189     if(m_timer_workaround.fieldevents_filter_active)
190     {
191         return;
192     }
193 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
194 
195     if (field_state == NRFX_NFC_FIELD_STATE_UNKNOWN)
196     {
197         /* Probe NFC field */
198         field_state = (nrfx_nfct_field_check()) ? NRFX_NFC_FIELD_STATE_ON :
199                                                   NRFX_NFC_FIELD_STATE_OFF;
200     }
201 
202     /* Field event service. Only take action on field transition -
203      * based on the value of m_nfct_cb.field_on
204      */
205     switch (field_state)
206     {
207         case NRFX_NFC_FIELD_STATE_ON:
208             if (!m_nfct_cb.field_on)
209             {
210 #if NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
211 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
212                 m_timer_workaround.is_hfclk_on               = false;
213                 m_timer_workaround.is_delayed                = false;
214                 m_timer_workaround.fieldevents_filter_active = true;
215 
216                 nrfx_timer_clear(&m_timer_workaround.timer);
217                 nrfx_timer_enable(&m_timer_workaround.timer);
218 #elif NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
219                 nrfx_timer_clear(&m_timer_workaround.timer);
220                 nrfx_timer_enable(&m_timer_workaround.timer);
221                 m_timer_workaround.field_state_cnt = 0;
222 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
223 #endif // NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
224 
225                 m_nfct_cb.field_on = true;
226                 nfct_evt.evt_id    = NRFX_NFCT_EVT_FIELD_DETECTED;
227                 NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
228             }
229             break;
230 
231         case NRFX_NFC_FIELD_STATE_OFF:
232             if (m_nfct_cb.field_on)
233             {
234                 nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_SENSE);
235                 nrf_nfct_int_disable(NRF_NFCT, NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
236                 m_nfct_cb.field_on = false;
237                 nfct_evt.evt_id    = NRFX_NFCT_EVT_FIELD_LOST;
238 
239                 /* Begin: Workaround for anomaly 218 */
240                 nrfx_nfct_frame_delay_max_set(true);
241                 /* End: Workaround for anomaly 218 */
242 
243                 NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
244             }
245             break;
246 
247         default:
248             /* No implementation required */
249             break;
250     }
251 }
252 
253 #if NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
254 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
nrfx_nfct_activate_check(void)255 static void nrfx_nfct_activate_check(void)
256 {
257     static bool is_field_validation_pending = false;
258 
259     if (is_field_validation_pending)
260     {
261         is_field_validation_pending                  = false;
262         m_timer_workaround.fieldevents_filter_active = false;
263 
264         // Check the field status and take action if field is lost.
265         nrfx_nfct_field_event_handler(NRFX_NFC_FIELD_STATE_UNKNOWN);
266         return;
267     }
268 
269     if ((m_timer_workaround.is_hfclk_on) && (m_timer_workaround.is_delayed))
270     {
271         nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_ACTIVATE);
272         is_field_validation_pending = true;
273 
274         // Start the timer second time to validate whether the tag has locked to the field.
275         nrfx_timer_clear(&m_timer_workaround.timer);
276         nrfx_timer_enable(&m_timer_workaround.timer);
277     }
278 }
279 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
280 
281 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
282 /* Begin: Workaround for anomaly 116 */
nrfx_nfct_reset(void)283 static inline void nrfx_nfct_reset(void)
284 {
285     uint32_t                       fdmax;
286     uint32_t                       fdmin;
287     uint32_t                       int_enabled;
288     uint8_t                        nfcid1[NRF_NFCT_SENSRES_NFCID1_SIZE_TRIPLE];
289     nrf_nfct_sensres_nfcid1_size_t nfcid1_size;
290     nrf_nfct_selres_protocol_t     protocol;
291 
292     // Save parameter settings before the reset of the NFCT peripheral.
293     fdmax       = nrf_nfct_frame_delay_max_get(NRF_NFCT);
294     fdmin       = nrf_nfct_frame_delay_min_get(NRF_NFCT);
295     nfcid1_size = nrf_nfct_nfcid1_get(NRF_NFCT, nfcid1);
296     protocol    = nrf_nfct_selres_protocol_get(NRF_NFCT);
297     int_enabled = nrf_nfct_int_enable_get(NRF_NFCT);
298 
299     // Reset the NFCT peripheral.
300     *(volatile uint32_t *)0x40005FFC = 0;
301     *(volatile uint32_t *)0x40005FFC;
302     *(volatile uint32_t *)0x40005FFC = 1;
303 
304     // Restore parameter settings after the reset of the NFCT peripheral.
305     nrf_nfct_frame_delay_max_set(NRF_NFCT, fdmax);
306     nrf_nfct_frame_delay_min_set(NRF_NFCT, fdmin);
307     nrf_nfct_nfcid1_set(NRF_NFCT, nfcid1, nfcid1_size);
308     nrf_nfct_selres_protocol_set(NRF_NFCT, protocol);
309 
310     // Restore general HW configuration.
311     nrfx_nfct_hw_init_setup();
312 
313     // Restore interrupts.
314     nrf_nfct_int_enable(NRF_NFCT, int_enabled);
315 
316     // Disable interrupts associated with data exchange.
317     nrf_nfct_int_disable(NRF_NFCT, NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
318 
319     NRFX_LOG_INFO("Reinitialize");
320 }
321 /* End: Workaround for anomaly 116 */
322 
nrfx_nfct_field_poll(void)323 static void nrfx_nfct_field_poll(void)
324 {
325     if (!nrfx_nfct_field_check())
326     {
327         if (++m_timer_workaround.field_state_cnt > NRFX_NFCT_FIELDLOST_THR)
328         {
329             nrfx_nfct_evt_t nfct_evt =
330             {
331                 .evt_id = NRFX_NFCT_EVT_FIELD_LOST,
332             };
333 
334             nrfx_timer_disable(&m_timer_workaround.timer);
335             m_nfct_cb.field_on = false;
336 
337             nrfx_nfct_frame_delay_max_set(true);
338 
339             /* Begin: Workaround for anomaly 116 */
340             /* resume the NFCT to initialized state */
341             nrfx_nfct_reset();
342             /* End: Workaround for anomaly 116 */
343 
344             NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
345         }
346         return;
347     }
348 
349     m_timer_workaround.field_state_cnt = 0;
350 }
351 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
352 
nrfx_nfct_field_timer_handler(nrf_timer_event_t event_type,void * p_context)353 static void nrfx_nfct_field_timer_handler(nrf_timer_event_t event_type, void * p_context)
354 {
355     (void)p_context;
356 
357     if (event_type != NRF_TIMER_EVENT_COMPARE0)
358     {
359         return;
360     }
361 
362 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
363     m_timer_workaround.is_delayed = true;
364 
365     nrfx_timer_disable(&m_timer_workaround.timer);
366     nrfx_nfct_activate_check();
367 #elif NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
368     nrfx_nfct_field_poll();
369 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
370 }
371 
nrfx_nfct_field_timer_config(void)372 static inline nrfx_err_t nrfx_nfct_field_timer_config(void)
373 {
374     nrfx_err_t err_code;
375     nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG(FIELD_TIMER_FREQUENCY_HZ);
376     timer_cfg.interrupt_priority = NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY;
377 
378     err_code = nrfx_timer_init(&m_timer_workaround.timer,
379                                &timer_cfg,
380                                nrfx_nfct_field_timer_handler);
381     if (err_code != NRFX_SUCCESS)
382     {
383         return err_code;
384     }
385 
386     nrfx_timer_extended_compare(&m_timer_workaround.timer,
387                                 NRF_TIMER_CC_CHANNEL0,
388                                 nrfx_timer_us_to_ticks(&m_timer_workaround.timer,
389                                                        NRFX_NFCT_TIMER_PERIOD),
390                                 NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
391                                 true);
392     return err_code;
393 }
394 #endif // NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
395 
396 static inline
nrf_nfct_nfcid1_size_to_sensres_size(uint8_t nfcid1_size)397 nrf_nfct_sensres_nfcid1_size_t nrf_nfct_nfcid1_size_to_sensres_size(uint8_t nfcid1_size)
398 {
399     switch (nfcid1_size)
400     {
401         case NRFX_NFCT_NFCID1_SINGLE_SIZE:
402             return NRF_NFCT_SENSRES_NFCID1_SIZE_SINGLE;
403 
404         case NRFX_NFCT_NFCID1_DOUBLE_SIZE:
405             return NRF_NFCT_SENSRES_NFCID1_SIZE_DOUBLE;
406 
407         case NRFX_NFCT_NFCID1_TRIPLE_SIZE:
408             return NRF_NFCT_SENSRES_NFCID1_SIZE_TRIPLE;
409 
410         default:
411             return NRF_NFCT_SENSRES_NFCID1_SIZE_DOUBLE;
412     }
413 }
414 
nrfx_nfct_rxtx_int_enable(uint32_t rxtx_int_mask)415 static inline void nrfx_nfct_rxtx_int_enable(uint32_t rxtx_int_mask)
416 {
417     nrf_nfct_int_enable(NRF_NFCT, rxtx_int_mask & m_nfct_cb.config.rxtx_int_mask);
418 }
419 
nrfx_nfct_init(nrfx_nfct_config_t const * p_config)420 nrfx_err_t nrfx_nfct_init(nrfx_nfct_config_t const * p_config)
421 {
422     NRFX_ASSERT(p_config);
423 
424     nrfx_err_t err_code = NRFX_SUCCESS;
425 
426     if (m_nfct_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
427     {
428         return NRFX_ERROR_INVALID_STATE;
429     }
430 
431     m_nfct_cb.config = *p_config;
432     nrfx_nfct_hw_init_setup();
433 
434     NRFX_IRQ_PENDING_CLEAR(NFCT_IRQn);
435     NRFX_IRQ_PRIORITY_SET(NFCT_IRQn, NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY);
436     NRFX_IRQ_ENABLE(NFCT_IRQn);
437 
438 #if NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
439     /* Initialize Timer module as the workaround for NFCT HW issues. */
440     err_code = nrfx_nfct_field_timer_config();
441 #endif // NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
442 
443     m_nfct_cb.state           = NRFX_DRV_STATE_INITIALIZED;
444     m_nfct_cb.frame_delay_max = NFCT_FRAMEDELAYMAX_DEFAULT;
445     m_nfct_cb.frame_delay_min = NFCT_FRAMEDELAYMIN_DEFAULT;
446 
447     NRFX_LOG_INFO("Initialized");
448     return err_code;
449 }
450 
nrfx_nfct_uninit(void)451 void nrfx_nfct_uninit(void)
452 {
453     nrfx_nfct_disable();
454 
455     NRFX_IRQ_DISABLE(NFCT_IRQn);
456     NRFX_IRQ_PENDING_CLEAR(NFCT_IRQn);
457 
458 #if NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
459     /* De-initialize Timer module as the workaround for NFCT HW issues. */
460     nrfx_timer_uninit(&m_timer_workaround.timer);
461 #endif // NRFX_CHECK(NFCT_WORKAROUND_USES_TIMER)
462 
463     m_nfct_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
464 }
465 
nrfx_nfct_enable(void)466 void nrfx_nfct_enable(void)
467 {
468     nrf_nfct_error_status_clear(NRF_NFCT, NRFX_NFCT_ERROR_STATUS_ALL_MASK);
469     nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_SENSE);
470 
471     nrf_nfct_int_enable(NRF_NFCT, NRF_NFCT_INT_FIELDDETECTED_MASK |
472                                   NRF_NFCT_INT_ERROR_MASK         |
473                                   NRF_NFCT_INT_SELECTED_MASK);
474 #if !NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
475     nrf_nfct_int_enable(NRF_NFCT, NRF_NFCT_INT_FIELDLOST_MASK);
476 #endif // !NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
477 
478     NRFX_LOG_INFO("Start");
479 }
480 
nrfx_nfct_disable(void)481 void nrfx_nfct_disable(void)
482 {
483     nrf_nfct_int_disable(NRF_NFCT, NRF_NFCT_DISABLE_ALL_INT);
484     nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_DISABLE);
485 
486     NRFX_LOG_INFO("Stop");
487 }
488 
nrfx_nfct_field_check(void)489 bool nrfx_nfct_field_check(void)
490 {
491     uint32_t const field_state = nrf_nfct_field_status_get(NRF_NFCT);
492 
493     if (((field_state & NRF_NFCT_FIELD_STATE_PRESENT_MASK) == 0) &&
494         ((field_state & NRF_NFCT_FIELD_STATE_LOCK_MASK) == 0))
495     {
496         /* Field is not active */
497         return false;
498     }
499 
500     return true;
501 }
502 
nrfx_nfct_rx(nrfx_nfct_data_desc_t const * p_tx_data)503 void nrfx_nfct_rx(nrfx_nfct_data_desc_t const * p_tx_data)
504 {
505     NRFX_ASSERT(p_tx_data);
506 
507     nrf_nfct_rxtx_buffer_set(NRF_NFCT, (uint8_t *) p_tx_data->p_data, p_tx_data->data_size);
508 
509     nrfx_nfct_rxtx_int_enable(NRFX_NFCT_RX_INT_MASK);
510     nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_ENABLERXDATA);
511 }
512 
nrfx_nfct_tx(nrfx_nfct_data_desc_t const * p_tx_data,nrf_nfct_frame_delay_mode_t delay_mode)513 nrfx_err_t nrfx_nfct_tx(nrfx_nfct_data_desc_t const * p_tx_data,
514                         nrf_nfct_frame_delay_mode_t   delay_mode)
515 {
516     NRFX_ASSERT(p_tx_data);
517     NRFX_ASSERT(p_tx_data->p_data);
518 
519     nrfx_err_t err = NRFX_SUCCESS;
520 
521     if (p_tx_data->data_size == 0)
522     {
523         return NRFX_ERROR_INVALID_LENGTH;
524     }
525 
526     NRFX_CRITICAL_SECTION_ENTER();
527 
528     /* In case when NFC frame transmission has already started, it returns an error. */
529     if (NRFX_NFCT_EVT_ACTIVE(TXFRAMESTART))
530     {
531         err = NRFX_ERROR_BUSY;
532     }
533     else
534     {
535         /* In case when Tx operation was scheduled with delay, stop scheduled Tx operation. */
536 #if defined(NRF52_SERIES)
537         *(volatile uint32_t *)0x40005010 = 0x01;
538 #elif defined(NRF5340_XXAA_APPLICATION) && defined(NRF_TRUSTZONE_NONSECURE)
539         *(volatile uint32_t *)0x4002D010 = 0x01;
540 #elif defined(NRF5340_XXAA_APPLICATION)
541         *(volatile uint32_t *)0x5002D010 = 0x01;
542 #endif
543         nrf_nfct_rxtx_buffer_set(NRF_NFCT, (uint8_t *) p_tx_data->p_data, p_tx_data->data_size);
544         nrf_nfct_tx_bits_set(NRF_NFCT, NRFX_NFCT_BYTES_TO_BITS(p_tx_data->data_size));
545         nrf_nfct_frame_delay_mode_set(NRF_NFCT, (nrf_nfct_frame_delay_mode_t) delay_mode);
546         nrfx_nfct_frame_delay_max_set(false);
547 
548         nrfx_nfct_rxtx_int_enable(NRFX_NFCT_TX_INT_MASK);
549         nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_STARTTX);
550     }
551 
552     NRFX_CRITICAL_SECTION_EXIT();
553 
554     if (err == NRFX_SUCCESS)
555     {
556         NRFX_LOG_INFO("Tx start");
557     }
558 
559     return err;
560 }
561 
nrfx_nfct_bits_tx(nrfx_nfct_data_desc_t const * p_tx_data,nrf_nfct_frame_delay_mode_t delay_mode)562 nrfx_err_t nrfx_nfct_bits_tx(nrfx_nfct_data_desc_t const * p_tx_data,
563                              nrf_nfct_frame_delay_mode_t   delay_mode)
564 {
565     NRFX_ASSERT(p_tx_data);
566     NRFX_ASSERT(p_tx_data->p_data);
567 
568     nrfx_err_t err = NRFX_SUCCESS;
569 
570     if (p_tx_data->data_size == 0)
571     {
572         return NRFX_ERROR_INVALID_LENGTH;
573     }
574 
575     /* Get buffer length, add additional byte if bits go beyond last whole byte */
576     uint32_t buffer_length = NRFX_NFCT_BITS_TO_BYTES(p_tx_data->data_size);
577     if (p_tx_data->data_size & NFCT_TXD_AMOUNT_TXDATABITS_Msk)
578     {
579         ++buffer_length;
580     }
581 
582     NRFX_CRITICAL_SECTION_ENTER();
583 
584     /* In case when NFC frame transmission has already started, it returns an error. */
585     if (NRFX_NFCT_EVT_ACTIVE(TXFRAMESTART))
586     {
587         err = NRFX_ERROR_BUSY;
588     }
589     else
590     {
591         /* In case when Tx operation was scheduled with delay, stop scheduled Tx operation. */
592 #if defined(NRF52_SERIES)
593         *(volatile uint32_t *)0x40005010 = 0x01;
594 #elif defined(NRF5340_XXAA_APPLICATION) && defined(NRF_TRUSTZONE_NONSECURE)
595         *(volatile uint32_t *)0x4002D010 = 0x01;
596 #elif defined(NRF5340_XXAA_APPLICATION)
597         *(volatile uint32_t *)0x5002D010 = 0x01;
598 #endif
599         nrf_nfct_rxtx_buffer_set(NRF_NFCT, (uint8_t *) p_tx_data->p_data, buffer_length);
600         nrf_nfct_tx_bits_set(NRF_NFCT, p_tx_data->data_size);
601         nrf_nfct_frame_delay_mode_set(NRF_NFCT, (nrf_nfct_frame_delay_mode_t) delay_mode);
602         nrfx_nfct_frame_delay_max_set(false);
603 
604         nrfx_nfct_rxtx_int_enable(NRFX_NFCT_TX_INT_MASK);
605         nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_STARTTX);
606     }
607 
608     NRFX_CRITICAL_SECTION_EXIT();
609 
610     if (err == NRFX_SUCCESS)
611     {
612         NRFX_LOG_INFO("Tx start");
613     }
614 
615     return err;
616 }
617 
nrfx_nfct_state_force(nrfx_nfct_state_t state)618 void nrfx_nfct_state_force(nrfx_nfct_state_t state)
619 {
620 #if NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
621     if (state == NRFX_NFCT_STATE_ACTIVATED)
622     {
623         m_timer_workaround.is_hfclk_on = true;
624         /* NFCT will be activated based on additional conditions */
625         nrfx_nfct_activate_check();
626         return;
627     }
628 #endif // NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_190)
629     nrf_nfct_task_trigger(NRF_NFCT, (nrf_nfct_task_t) state);
630 }
631 
nrfx_nfct_init_substate_force(nrfx_nfct_active_state_t sub_state)632 void nrfx_nfct_init_substate_force(nrfx_nfct_active_state_t sub_state)
633 {
634     if (sub_state == NRFX_NFCT_ACTIVE_STATE_DEFAULT)
635     {
636 #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
637         if (((*(uint32_t volatile *)(0x40005420)) & 0x1UL) == (1UL))
638 #else
639         if (nrf_nfct_sleep_state_get(NRF_NFCT) == NRF_NFCT_SLEEP_STATE_SLEEP_A)
640 #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
641         {
642             // Default state is SLEEP_A
643             nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_GOSLEEP);
644         }
645         else
646         {
647             // Default state is IDLE
648             nrf_nfct_task_trigger(NRF_NFCT, NRF_NFCT_TASK_GOIDLE);
649         }
650     }
651     else
652     {
653         nrf_nfct_task_trigger(NRF_NFCT, (nrf_nfct_task_t) sub_state);
654     }
655 
656     nrfx_nfct_frame_delay_max_set(true);
657 
658     /* Disable TX/RX here (will be enabled at SELECTED) */
659     nrf_nfct_int_disable(NRF_NFCT, NRFX_NFCT_RX_INT_MASK | NRFX_NFCT_TX_INT_MASK);
660 }
661 
nrfx_nfct_parameter_set(nrfx_nfct_param_t const * p_param)662 nrfx_err_t nrfx_nfct_parameter_set(nrfx_nfct_param_t const * p_param)
663 {
664     NRFX_ASSERT(p_param);
665 
666     switch (p_param->id)
667     {
668         case NRFX_NFCT_PARAM_ID_FDT:
669         {
670             uint32_t delay     = p_param->data.fdt;
671             uint32_t delay_thr = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk;
672             uint32_t delay_max;
673 
674             delay_max = (delay > delay_thr) ? delay_thr : delay;
675             if (delay_max < m_nfct_cb.frame_delay_min)
676             {
677                 return NRFX_ERROR_INVALID_PARAM;
678             }
679 
680             m_nfct_cb.frame_delay_max = delay_max;
681             break;
682         }
683 
684         case NRFX_NFCT_PARAM_ID_FDT_MIN:
685         {
686             uint32_t delay = p_param->data.fdt_min;
687             uint32_t delay_thr = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk;
688             uint32_t delay_min;
689 
690             delay_min = (delay > delay_thr) ? delay_thr : delay;
691             if (delay_min > m_nfct_cb.frame_delay_max)
692             {
693                 return NRFX_ERROR_INVALID_PARAM;
694             }
695 
696             m_nfct_cb.frame_delay_min = delay_min;
697             nrf_nfct_frame_delay_min_set(NRF_NFCT, m_nfct_cb.frame_delay_min);
698             break;
699         }
700 
701         case NRFX_NFCT_PARAM_ID_SEL_RES:
702             if (p_param->data.sel_res_protocol > NRF_NFCT_SELRES_PROTOCOL_NFCDEP_T4AT)
703             {
704                 return NRFX_ERROR_INVALID_PARAM;
705             }
706 
707             nrf_nfct_selres_protocol_set(NRF_NFCT,
708                     (nrf_nfct_selres_protocol_t) p_param->data.sel_res_protocol);
709             break;
710 
711         case NRFX_NFCT_PARAM_ID_NFCID1:
712         {
713             nrf_nfct_sensres_nfcid1_size_t id_size_mask;
714 
715             id_size_mask = nrf_nfct_nfcid1_size_to_sensres_size(p_param->data.nfcid1.id_size);
716             nrf_nfct_nfcid1_set(NRF_NFCT, p_param->data.nfcid1.p_id, id_size_mask);
717             break;
718         }
719 
720         default:
721             break;
722     }
723 
724     return NRFX_SUCCESS;
725 }
726 
nrfx_nfct_nfcid1_default_bytes_get(uint8_t * const p_nfcid1_buff,uint32_t nfcid1_buff_len)727 nrfx_err_t nrfx_nfct_nfcid1_default_bytes_get(uint8_t * const p_nfcid1_buff,
728                                               uint32_t        nfcid1_buff_len)
729 {
730     if ((nfcid1_buff_len != NRFX_NFCT_NFCID1_SINGLE_SIZE) &&
731         (nfcid1_buff_len != NRFX_NFCT_NFCID1_DOUBLE_SIZE) &&
732         (nfcid1_buff_len != NRFX_NFCT_NFCID1_TRIPLE_SIZE))
733     {
734         return NRFX_ERROR_INVALID_LENGTH;
735     }
736 
737 #if defined(FICR_NFC_TAGHEADER0_MFGID_Msk) && !defined(NRF_TRUSTZONE_NONSECURE)
738     uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0;
739     uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1;
740     uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2;
741 #else
742     uint32_t nfc_tag_header0 = 0x5F;
743     uint32_t nfc_tag_header1 = 0;
744     uint32_t nfc_tag_header2 = 0;
745 #endif
746 
747     p_nfcid1_buff[0] = (uint8_t) (nfc_tag_header0 >> 0);
748     p_nfcid1_buff[1] = (uint8_t) (nfc_tag_header0 >> 8);
749     p_nfcid1_buff[2] = (uint8_t) (nfc_tag_header0 >> 16);
750     p_nfcid1_buff[3] = (uint8_t) (nfc_tag_header1 >> 0);
751 
752     if (nfcid1_buff_len != NRFX_NFCT_NFCID1_SINGLE_SIZE)
753     {
754         p_nfcid1_buff[4] = (uint8_t) (nfc_tag_header1 >> 8);
755         p_nfcid1_buff[5] = (uint8_t) (nfc_tag_header1 >> 16);
756         p_nfcid1_buff[6] = (uint8_t) (nfc_tag_header1 >> 24);
757 
758         if (nfcid1_buff_len == NRFX_NFCT_NFCID1_TRIPLE_SIZE)
759         {
760             p_nfcid1_buff[7] = (uint8_t) (nfc_tag_header2 >> 0);
761             p_nfcid1_buff[8] = (uint8_t) (nfc_tag_header2 >> 8);
762             p_nfcid1_buff[9] = (uint8_t) (nfc_tag_header2 >> 16);
763         }
764         /* Begin: Workaround for anomaly 181. */
765         /* Workaround for wrong value in NFCID1. Value 0x88 cannot be used as byte 3
766            of a double-size NFCID1, according to the NFC Forum Digital Protocol specification. */
767         else if (p_nfcid1_buff[3] == 0x88)
768         {
769             p_nfcid1_buff[3] |= 0x11;
770         }
771         /* End: Workaround for anomaly 181 */
772     }
773 
774     return NRFX_SUCCESS;
775 }
776 
nrfx_nfct_autocolres_enable(void)777 void nrfx_nfct_autocolres_enable(void)
778 {
779 #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
780     (*(uint32_t *)(0x4000559C)) &= (~(0x1UL));
781 #else
782     nrf_nfct_autocolres_enable(NRF_NFCT);
783 #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
784 }
785 
nrfx_nfct_autocolres_disable(void)786 void nrfx_nfct_autocolres_disable(void)
787 {
788 #if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
789     (*(uint32_t *)(0x4000559C)) |= (0x1UL);
790 #else
791     nrf_nfct_autocolres_disable(NRF_NFCT);
792 #endif //defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
793 }
794 
nrfx_nfct_irq_handler(void)795 void nrfx_nfct_irq_handler(void)
796 {
797     nrfx_nfct_field_state_t current_field = NRFX_NFC_FIELD_STATE_NONE;
798 
799     if (NRFX_NFCT_EVT_ACTIVE(FIELDDETECTED))
800     {
801         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_FIELDDETECTED);
802         current_field = NRFX_NFC_FIELD_STATE_ON;
803 
804         NRFX_LOG_DEBUG("Field detected");
805     }
806 
807 #if !NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
808     if (NRFX_NFCT_EVT_ACTIVE(FIELDLOST))
809     {
810         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_FIELDLOST);
811         current_field = (current_field == NRFX_NFC_FIELD_STATE_NONE) ?
812                         NRFX_NFC_FIELD_STATE_OFF : NRFX_NFC_FIELD_STATE_UNKNOWN;
813 
814         NRFX_LOG_DEBUG("Field lost");
815     }
816 #endif //!NRFX_CHECK(USE_WORKAROUND_FOR_ANOMALY_79)
817 
818     /* Perform actions if any FIELD event is active */
819     if (current_field != NRFX_NFC_FIELD_STATE_NONE)
820     {
821         nrfx_nfct_field_event_handler(current_field);
822     }
823 
824     if (NRFX_NFCT_EVT_ACTIVE(RXFRAMESTART))
825     {
826         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_RXFRAMESTART);
827 
828         nrfx_nfct_evt_t nfct_evt =
829         {
830             .evt_id = NRFX_NFCT_EVT_RX_FRAMESTART
831         };
832 
833         NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
834     }
835 
836     if (NRFX_NFCT_EVT_ACTIVE(RXFRAMEEND))
837     {
838         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_RXFRAMEEND);
839 
840         nrfx_nfct_evt_t nfct_evt =
841         {
842             .evt_id = NRFX_NFCT_EVT_RX_FRAMEEND
843         };
844 
845         /* Take into account only the number of whole bytes. */
846         nfct_evt.params.rx_frameend.rx_status         = 0;
847         nfct_evt.params.rx_frameend.rx_data.p_data    = nrf_nfct_rxtx_buffer_get(NRF_NFCT);
848         nfct_evt.params.rx_frameend.rx_data.data_size =
849             NRFX_NFCT_BITS_TO_BYTES(nrf_nfct_rx_bits_get(NRF_NFCT, true));
850 
851         if (NRFX_NFCT_EVT_ACTIVE(RXERROR))
852         {
853             nfct_evt.params.rx_frameend.rx_status =
854                 (nrf_nfct_rx_frame_status_get(NRF_NFCT) & NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
855             nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_RXERROR);
856 
857             NRFX_LOG_DEBUG("Rx error (0x%x)", (unsigned int) nfct_evt.params.rx_frameend.rx_status);
858 
859             /* Clear rx frame status */
860             nrf_nfct_rx_frame_status_clear(NRF_NFCT, NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
861         }
862 
863         NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
864 
865         NRFX_LOG_DEBUG("Rx fend");
866     }
867 
868     if (NRFX_NFCT_EVT_ACTIVE(SELECTED))
869     {
870         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_SELECTED);
871         /* Clear also RX END and RXERROR events because SW does not take care of
872            commands that were received before selecting the tag. */
873         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_RXFRAMEEND);
874         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_RXERROR);
875         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_TXFRAMESTART);
876         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_TXFRAMEEND);
877 
878         nrfx_nfct_frame_delay_max_set(false);
879 
880         /* At this point any previous error status can be ignored. */
881         nrf_nfct_rx_frame_status_clear(NRF_NFCT, NRFX_NFCT_FRAME_STATUS_RX_ALL_MASK);
882         nrf_nfct_error_status_clear(NRF_NFCT, NRFX_NFCT_ERROR_STATUS_ALL_MASK);
883 
884         nrfx_nfct_evt_t nfct_evt =
885         {
886             .evt_id = NRFX_NFCT_EVT_SELECTED
887         };
888         NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
889 
890         NRFX_LOG_DEBUG("Selected");
891     }
892 
893     if (NRFX_NFCT_EVT_ACTIVE(ERROR))
894     {
895         uint32_t err_status = nrf_nfct_error_status_get(NRF_NFCT);
896         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_ERROR);
897 
898         nrfx_nfct_evt_t nfct_evt =
899         {
900             .evt_id = NRFX_NFCT_EVT_ERROR
901         };
902 
903         /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received. */
904         if (err_status & NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK)
905         {
906             nrf_nfct_error_status_clear(NRF_NFCT, NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK);
907 
908             nfct_evt.params.error.reason = NRFX_NFCT_ERROR_FRAMEDELAYTIMEOUT;
909             NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
910         }
911 
912         /* Report any other error. */
913         err_status &= ~NRF_NFCT_ERROR_FRAMEDELAYTIMEOUT_MASK;
914         if (err_status)
915         {
916             NRFX_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status);
917         }
918 
919         /* Clear error status. */
920         nrf_nfct_error_status_clear(NRF_NFCT, NRFX_NFCT_ERROR_STATUS_ALL_MASK);
921     }
922 
923     if (NRFX_NFCT_EVT_ACTIVE(TXFRAMESTART))
924     {
925         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_TXFRAMESTART);
926 
927         if (m_nfct_cb.config.cb != NULL)
928         {
929             nrfx_nfct_evt_t nfct_evt;
930 
931             nfct_evt.evt_id                                 = NRFX_NFCT_EVT_TX_FRAMESTART;
932             nfct_evt.params.tx_framestart.tx_data.p_data    = nrf_nfct_rxtx_buffer_get(NRF_NFCT);
933             nfct_evt.params.tx_framestart.tx_data.data_size =
934                 NRFX_NFCT_BITS_TO_BYTES(nrf_nfct_tx_bits_get(NRF_NFCT));
935 
936             m_nfct_cb.config.cb(&nfct_evt);
937         }
938     }
939 
940     if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
941     {
942         nrf_nfct_event_clear(NRF_NFCT, NRF_NFCT_EVENT_TXFRAMEEND);
943 
944         nrfx_nfct_evt_t nfct_evt =
945         {
946             .evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
947         };
948 
949         /* Ignore any frame transmission until a new TX is scheduled by nrfx_nfct_tx() */
950         nrf_nfct_int_disable(NRF_NFCT, NRFX_NFCT_TX_INT_MASK);
951 
952         NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
953 
954         NRFX_LOG_DEBUG("Tx fend");
955     }
956 }
957 
958 #endif // NRFX_CHECK(NRFX_NFCT_ENABLED)
959