Skip to content

Commit

Permalink
nfc: NFC platform support for nRF54h20
Browse files Browse the repository at this point in the history
This adds support for nRF54h20 in the NFC platform
integration layer for NFC T2T and NFC T4T libraries.

NCSDK-20697

Signed-off-by: Kamil Gawor <[email protected]>
  • Loading branch information
KAGA164 authored and cvinayak committed Jan 25, 2024
1 parent 616169f commit 849aea6
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 18 deletions.
4 changes: 4 additions & 0 deletions subsys/nfc/lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
119 changes: 102 additions & 17 deletions subsys/nfc/lib/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,26 @@
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/kernel.h>
#include <zephyr/linker/devicetree_regions.h>

#if !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX)
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#endif /* !IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) */

#include <zephyr/sys/__assert.h>
#include <zephyr/sys/onoff.h>

#include <nrf_erratas.h>

#include <nrfx_nfct.h>
#include <nrfx_timer.h>
#include <hal/nrf_ficr.h>

#include <nfc_platform.h>

#include "platform_internal.h"

#if defined(CONFIG_BUILD_WITH_TFM)
Expand All @@ -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)
{
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 849aea6

Please sign in to comment.