diff --git a/subsys/nfc/lib/Kconfig b/subsys/nfc/lib/Kconfig index 668e8d7ac02..483db38b6bd 100644 --- a/subsys/nfc/lib/Kconfig +++ b/subsys/nfc/lib/Kconfig @@ -84,6 +84,10 @@ endif# NFC_OWN_THREAD config NFC_LOW_LATENCY_IRQ bool "Use low latency IRQ for NFC" default y + # NFC low latency interrupt requires software interrupt being supported. + default y if $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_EGU)) || \ + $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_SWI)) + select ZERO_LATENCY_IRQS help Using this option ensures fast NFC interrupt execution on the cost of using additional interrupt (SWI). diff --git a/subsys/nfc/lib/platform.c b/subsys/nfc/lib/platform.c index a949c0415ec..59c71cf9941 100644 --- a/subsys/nfc/lib/platform.c +++ b/subsys/nfc/lib/platform.c @@ -3,12 +3,26 @@ * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ + #include +#include + +#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) #include #include +#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */ + +#include +#include + +#include + #include #include +#include + #include + #include "platform_internal.h" #if defined(CONFIG_BUILD_WITH_TFM) @@ -19,17 +33,59 @@ LOG_MODULE_REGISTER(nfc_platform, CONFIG_NFC_PLATFORM_LOG_LEVEL); +#if NRF53_ERRATA_70_ENABLE_WORKAROUND || NRF52_ERRATA_190_ENABLE_WORKAROUND || \ + NRF52_ERRATA_79_ENABLE_WORKAROUND + #define NFC_PLATFORM_USE_TIMER_WORKAROUND 1 +#else + #define NFC_PLATFORM_USE_TIMER_WORKAROUND 0 +#endif + +#if NFC_PLATFORM_USE_TIMER_WORKAROUND #define NFC_TIMER_IRQn NRFX_CONCAT_3(TIMER, \ NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID, \ _IRQn) #define nfc_timer_irq_handler NRFX_CONCAT_3(nrfx_timer_, \ NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID, \ _irq_handler) +#endif /* NFC_PLATFORM_USE_TIMER_WORKAROUND */ #define DT_DRV_COMPAT nordic_nrf_clock +#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) static struct onoff_manager *hf_mgr; static struct onoff_client cli; +#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */ + +#define NFCT DT_NODELABEL(nfct) +#define NFCT_HAS_PROPERTY(_property) \ + DT_NODE_HAS_PROP(NFCT, _property) + +#define NFCT_MEMORY_SECTION \ + COND_CODE_1(NFCT_HAS_PROPERTY(memory_regions), \ + (__attribute__((section(LINKER_DT_NODE_REGION_NAME( \ + DT_PHANDLE(NFCT, memory_regions)))))), \ + ()) + +#define NFC_T2T_BUFFER_SIZE (IS_ENABLED(CONFIG_NFC_T2T_NRFXLIB) ? NFC_PLATFORM_T2T_BUFFER_SIZE : 0U) +#define NFC_T4T_BUFFER_SIZE (IS_ENABLED(CONFIG_NFC_T4T_NRFXLIB) ? NFC_PLATFORM_T4T_BUFFER_SIZE : 0U) + +#define NFCT_PLATFORM_BUFFER_SIZE MAX(NFC_T4T_BUFFER_SIZE, NFC_T2T_BUFFER_SIZE) + +/* NFC platform buffer. This buffer is used directly by the NFCT peripheral. + * It might need to be allocated in the specific memory section which can be accessed + * by EasyDMA. + */ +static uint8_t nfc_platform_buffer[NFCT_PLATFORM_BUFFER_SIZE] NFCT_MEMORY_SECTION; + +#if CONFIG_NFC_T2T_NRFXLIB + BUILD_ASSERT(sizeof(nfc_platform_buffer) >= NFC_T2T_BUFFER_SIZE, + "Minimal buffer size for the NFC T2T operations must be at least 16 bytes"); +#endif /* CONFIG_NFC_T2T_NRFXLIB */ + +#if CONFIG_NFC_T4T_NRFXLIB + BUILD_ASSERT(sizeof(nfc_platform_buffer) >= NFC_T4T_BUFFER_SIZE, + "Minimal buffer size for the NFC T4T operations must be at least 256 bytes"); +#endif /* CONFIG_NFC_T4T_NRFXLIB */ ISR_DIRECT_DECLARE(nfc_isr_wrapper) { @@ -49,17 +105,24 @@ static void clock_handler(struct onoff_manager *mgr, int res) nrfx_nfct_state_force(NRFX_NFCT_STATE_ACTIVATED); } -nrfx_err_t nfc_platform_setup(nfc_lib_cb_resolve_t nfc_lib_cb_resolve) +nrfx_err_t nfc_platform_setup(nfc_lib_cb_resolve_t nfc_lib_cb_resolve, uint8_t *p_irq_priority) { int err; +#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) hf_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); __ASSERT_NO_MSG(hf_mgr); +#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */ - IRQ_DIRECT_CONNECT(NFCT_IRQn, CONFIG_NFCT_IRQ_PRIORITY, + IRQ_DIRECT_CONNECT(DT_IRQN(NFCT), DT_IRQ(NFCT, priority), nfc_isr_wrapper, 0); - IRQ_CONNECT(NFC_TIMER_IRQn, CONFIG_NFCT_IRQ_PRIORITY, + +#if NFC_PLATFORM_USE_TIMER_WORKAROUND + IRQ_CONNECT(NFC_TIMER_IRQn, DT_IRQ(NFCT, priority), nfc_timer_irq_handler, NULL, 0); +#endif /* NFC_PLATFORM_USE_TIMER_WORKAROUND */ + + *p_irq_priority = DT_IRQ(NFCT, priority); err = nfc_platform_internal_init(nfc_lib_cb_resolve); if (err) { @@ -71,22 +134,14 @@ nrfx_err_t nfc_platform_setup(nfc_lib_cb_resolve_t nfc_lib_cb_resolve) return NRFX_SUCCESS; } - static nrfx_err_t nfc_platform_tagheaders_get(uint32_t tag_header[3]) { - __IOM FICR_NFC_Type *ficr_nfc = -#if defined(NRF_TRUSTZONE_NONSECURE) - &NRF_FICR_S->NFC; -#else - &NRF_FICR->NFC; -#endif - - #ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE #if defined(CONFIG_BUILD_WITH_TFM) uint32_t err = 0; enum tfm_platform_err_t plt_err; FICR_NFC_Type ficr_nfc_ns; + __IOM FICR_NFC_Type *ficr_nfc = &NRF_FICR_S->NFC; plt_err = tfm_platform_mem_read(&ficr_nfc_ns, (uint32_t)ficr_nfc, sizeof(ficr_nfc_ns), &err); @@ -96,15 +151,20 @@ static nrfx_err_t nfc_platform_tagheaders_get(uint32_t tag_header[3]) return NRFX_ERROR_INTERNAL; } - ficr_nfc = &ficr_nfc_ns; + tag_header[0] = ficr_nfc_ns.TAGHEADER0; + tag_header[1] = ficr_nfc_ns.TAGHEADER1; + tag_header[2] = ficr_nfc_ns.TAGHEADER2; + #else #error "Cannot read FICR NFC Tag Header in current configuration" #endif -#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ +#else - tag_header[0] = ficr_nfc->TAGHEADER0; - tag_header[1] = ficr_nfc->TAGHEADER1; - tag_header[2] = ficr_nfc->TAGHEADER2; + tag_header[0] = nrf_ficr_nfc_tagheader_get(NRF_FICR, 0); + tag_header[1] = nrf_ficr_nfc_tagheader_get(NRF_FICR, 1); + tag_header[2] = nrf_ficr_nfc_tagheader_get(NRF_FICR, 2); + +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ return NRFX_SUCCESS; } @@ -157,6 +217,20 @@ nrfx_err_t nfc_platform_nfcid1_default_bytes_get(uint8_t * const buf, return NRFX_SUCCESS; } +uint8_t *nfc_platform_buffer_alloc(size_t size) +{ + if (size > sizeof(nfc_platform_buffer)) { + __ASSERT_NO_MSG(false); + return NULL; + } + + return nfc_platform_buffer; +} + +void nfc_platform_buffer_free(uint8_t *p_buffer) +{ + ARG_UNUSED(p_buffer); +} void nfc_platform_event_handler(nrfx_nfct_evt_t const *event) { @@ -166,17 +240,28 @@ void nfc_platform_event_handler(nrfx_nfct_evt_t const *event) case NRFX_NFCT_EVT_FIELD_DETECTED: LOG_DBG("Field detected"); +#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) + /* For now, assume HFXO clock is running all the time on nRF54h20 + * and currently clock handling is not implemented on this platform. + */ sys_notify_init_callback(&cli.notify, clock_handler); err = onoff_request(hf_mgr, &cli); __ASSERT_NO_MSG(err >= 0); +#else + ARG_UNUSED(err); + /* HFXO is running, switch NFCT to active state immediately. */ + clock_handler(NULL, 0); +#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */ break; case NRFX_NFCT_EVT_FIELD_LOST: LOG_DBG("Field lost"); +#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) err = onoff_cancel_or_release(hf_mgr, &cli); __ASSERT_NO_MSG(err >= 0); +#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */ break; diff --git a/west.yml b/west.yml index f311d31d6ea..9e4ce8ec98c 100644 --- a/west.yml +++ b/west.yml @@ -142,7 +142,7 @@ manifest: - name: nrfxlib repo-path: sdk-nrfxlib path: nrfxlib - revision: 2c7d4c0ddd4d531798207d5a3b58bbf9412dc488 + revision: a9a80f315618c78a68c3f7d917de0db182ac121d - name: trusted-firmware-m repo-path: sdk-trusted-firmware-m path: modules/tee/tf-m/trusted-firmware-m