Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nfc: Introduce Zero Latency IRQ #13248

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ Libraries for NFC
-----------------

* Fixed an issue with handling zero size data (when receiving empty I-blocks from poller) in the :file:`platform_internal_thread` file.
* Added support for zero-latency interrupts for all NFC libraries.

nRF Security
------------
Expand Down
1 change: 1 addition & 0 deletions subsys/nfc/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
zephyr_library()
if(CONFIG_NFC_PLATFORM)
zephyr_library_sources(platform.c)
zephyr_library_sources(platform_internal_hfclk.c)
zephyr_library_sources_ifdef(CONFIG_NFC_THREAD_CALLBACK platform_internal_thread.c)
zephyr_library_sources_ifndef(CONFIG_NFC_THREAD_CALLBACK platform_internal_irq.c)
endif()
12 changes: 7 additions & 5 deletions subsys/nfc/lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ config NFC_THREAD_PRIORITY

endif# NFC_OWN_THREAD

config NFC_LOW_LATENCY_IRQ
bool "Use low latency IRQ for NFC"
default y
config NFC_ZERO_LATENCY_IRQ
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimental?

bool "Use zero latency IRQ for NFC"
default n
select ZERO_LATENCY_IRQS
select EXPERIMENTAL
help
Using this option ensures fast NFC interrupt
Using this option ensures zero latency NFC interrupt
execution on the cost of using additional interrupt (SWI).

if NFC_LOW_LATENCY_IRQ
if NFC_ZERO_LATENCY_IRQ

config NFC_SWI_NUMBER
int
Expand Down
51 changes: 9 additions & 42 deletions subsys/nfc/lib/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#include <nrfx_nfct.h>
#include <nrfx_timer.h>
#include <nfc_platform.h>
Expand All @@ -28,8 +26,11 @@ LOG_MODULE_REGISTER(nfc_platform, CONFIG_NFC_PLATFORM_LOG_LEVEL);

#define DT_DRV_COMPAT nordic_nrf_clock

static struct onoff_manager *hf_mgr;
static struct onoff_client cli;
#ifdef CONFIG_NFC_ZERO_LATENCY_IRQ
#define NFCT_IRQ_FLAGS IRQ_ZERO_LATENCY
#else
#define NFCT_IRQ_FLAGS 0
#endif /* CONFIG_NFC_ZERO_LATENCY_IRQ */

ISR_DIRECT_DECLARE(nfc_isr_wrapper)
{
Expand All @@ -43,21 +44,16 @@ ISR_DIRECT_DECLARE(nfc_isr_wrapper)
return 1;
}

static void clock_handler(struct onoff_manager *mgr, int res)
{
/* Activate NFCT only when HFXO is running */
nrfx_nfct_state_force(NRFX_NFCT_STATE_ACTIVATED);
}

nrfx_err_t nfc_platform_setup(nfc_lib_cb_resolve_t nfc_lib_cb_resolve)
{
int err;

hf_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
__ASSERT_NO_MSG(hf_mgr);
err = nfc_platform_internal_hfclk_init();
__ASSERT_NO_MSG(err == 0);

IRQ_DIRECT_CONNECT(NFCT_IRQn, CONFIG_NFCT_IRQ_PRIORITY,
nfc_isr_wrapper, 0);
nfc_isr_wrapper, NFCT_IRQ_FLAGS);

IRQ_CONNECT(NFC_TIMER_IRQn, CONFIG_NFCT_IRQ_PRIORITY,
nfc_timer_irq_handler, NULL, 0);

Expand Down Expand Up @@ -156,32 +152,3 @@ nrfx_err_t nfc_platform_nfcid1_default_bytes_get(uint8_t * const buf,

return NRFX_SUCCESS;
}


void nfc_platform_event_handler(nrfx_nfct_evt_t const *event)
{
int err;

switch (event->evt_id) {
case NRFX_NFCT_EVT_FIELD_DETECTED:
LOG_DBG("Field detected");

sys_notify_init_callback(&cli.notify, clock_handler);
err = onoff_request(hf_mgr, &cli);
__ASSERT_NO_MSG(err >= 0);

break;

case NRFX_NFCT_EVT_FIELD_LOST:
LOG_DBG("Field lost");

err = onoff_cancel_or_release(hf_mgr, &cli);
__ASSERT_NO_MSG(err >= 0);

break;

default:
/* No implementation required */
break;
}
}
27 changes: 27 additions & 0 deletions subsys/nfc/lib/platform_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,33 @@ extern "C" {
*/
int nfc_platform_internal_init(nfc_lib_cb_resolve_t cb_rslv);

/** @brief Initialize internal hfclk (high frequency clock) control.
*
* This function should not be used directly.
*
* @retval 0 If the operation was successful.
* @retval -EIO Initialization failed.
*/
int nfc_platform_internal_hfclk_init(void);

/** @brief Start hfclk.
*
* This function should not be used directly.
*
* @retval 0 If the operation was successful.
* Otherwise, a (negative) error code is returned.
*/
int nfc_platform_internal_hfclk_start(void);

/** @brief Stop hfclk.
*
* This function should not be used directly.
*
* @retval 0 If the operation was successful.
* Otherwise, a (negative) error code is returned.
*/
int nfc_platform_internal_hfclk_stop(void);

#ifdef __cplusplus
}
#endif
Expand Down
41 changes: 41 additions & 0 deletions subsys/nfc/lib/platform_internal_hfclk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>
#include <nrfx_nfct.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#include "platform_internal.h"

static struct onoff_manager *hf_mgr;
static struct onoff_client cli;

static void clock_handler(struct onoff_manager *mgr, int res)
{
/* Activate NFCT only when HFXO is running */
nrfx_nfct_state_force(NRFX_NFCT_STATE_ACTIVATED);
}

int nfc_platform_internal_hfclk_init(void)
{
hf_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);

if (hf_mgr) {
return 0;
} else {
return -EIO;
}
}

int nfc_platform_internal_hfclk_start(void)
{
sys_notify_init_callback(&cli.notify, clock_handler);
return onoff_request(hf_mgr, &cli);
}

int nfc_platform_internal_hfclk_stop(void)
{
return onoff_cancel_or_release(hf_mgr, &cli);
}
31 changes: 31 additions & 0 deletions subsys/nfc/lib/platform_internal_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include <nfc_platform.h>
#include "platform_internal.h"

#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(nfc_platform, CONFIG_NFC_PLATFORM_LOG_LEVEL);

static nfc_lib_cb_resolve_t nfc_cb_resolve;

int nfc_platform_internal_init(nfc_lib_cb_resolve_t cb_rslv)
Expand All @@ -28,3 +32,30 @@ void nfc_platform_cb_request(const void *ctx,
__ASSERT(nfc_cb_resolve != NULL, "nfc_cb_resolve is not set");
nfc_cb_resolve(ctx, data);
}

void nfc_platform_event_handler(nrfx_nfct_evt_t const *event)
{
int err;

switch (event->evt_id) {
case NRFX_NFCT_EVT_FIELD_DETECTED:
LOG_DBG("Field detected");

err = nfc_platform_internal_hfclk_start();
__ASSERT_NO_MSG(err >= 0);

break;

case NRFX_NFCT_EVT_FIELD_LOST:
LOG_DBG("Field lost");

err = nfc_platform_internal_hfclk_stop();
__ASSERT_NO_MSG(err >= 0);

break;

default:
/* No implementation required */
break;
}
}
Loading
Loading