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