diff --git a/include/nfc/tnep/tag.h b/include/nfc/tnep/tag.h index c11f4b4c88e0..06ba5e895413 100644 --- a/include/nfc/tnep/tag.h +++ b/include/nfc/tnep/tag.h @@ -17,9 +17,6 @@ #include #include -/** NFC TNEP library event count. */ -#define NFC_TNEP_EVENTS_NUMBER 2 - /** Maximum Service Waiting Time. */ #define NFC_TNEP_TAG_MAX_WAIT_TIME 63 @@ -188,8 +185,8 @@ int nfc_tnep_tag_tx_msg_buffer_register(uint8_t *tx_buff, /** * @brief Start communication using TNEP. * - * @param[out] events TNEP Tag Events. - * @param[in] event_cnt Event count. This library needs 2 events. + * @note This function must be called after @ref nfc_tnep_tag_signalling_init. + * * @param[in] payload_set Function for setting NDEF data for NFC TNEP * Tag Device. This library use it internally * to set raw NDEF message to the Tag NDEF file. @@ -199,8 +196,7 @@ int nfc_tnep_tag_tx_msg_buffer_register(uint8_t *tx_buff, * @retval 0 If the operation was successful. * Otherwise, a (negative) error code is returned. */ -int nfc_tnep_tag_init(struct k_poll_event *events, uint8_t event_cnt, - nfc_payload_set_t payload_set); +int nfc_tnep_tag_init(nfc_payload_set_t payload_set); /** * @brief Create the Initial TNEP NDEF message. diff --git a/include/nfc/tnep/tag_signalling.h b/include/nfc/tnep/tag_signalling.h new file mode 100644 index 000000000000..2c089c89e729 --- /dev/null +++ b/include/nfc/tnep/tag_signalling.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NFC_TNEP_TAG_SIGNALLING_H_ +#define NFC_TNEP_TAG_SIGNALLING_H_ + +#include + +enum tnep_event { + TNEP_EVENT_DUMMY, + TNEP_EVENT_MSG_RX_NEW, + TNEP_EVENT_TAG_SELECTED, +}; + +/** @brief Raises a receive event. + * + * @param event Event to be raised. + */ +void nfc_tnep_tag_signalling_rx_event_raise(enum tnep_event event); + +/** @brief Raises a transmit event. + * + * @param event Event to be raised. + */ +void nfc_tnep_tag_signalling_tx_event_raise(enum tnep_event event); + +/** @brief Checks and clears receive event. + * + * @param event Pointer to store the raised event. + * The value is valid only if the function returns @c true. + * + * @retval true if a receive event was raised. + * @retval false if no receive event was raised. + */ +bool nfc_tnep_tag_signalling_rx_event_check_and_clear(enum tnep_event *event); + +/** @brief Checks and clears transmit event. + * + * @param event Pointer to store the raised event. + * The value is valid only if the function returns @c true. + * + * @retval true if a transmit event was raised. + * @retval false if no transmit event was raised. + */ +bool nfc_tnep_tag_signalling_tx_event_check_and_clear(enum tnep_event *event); + +#endif /* NFC_TNEP_TAG_SIGNALLING_H_ */ diff --git a/include/nfc/tnep/tag_signalling_zephyr.h b/include/nfc/tnep/tag_signalling_zephyr.h new file mode 100644 index 000000000000..f84731952b7d --- /dev/null +++ b/include/nfc/tnep/tag_signalling_zephyr.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NFC_TNEP_TAG_SIGNALLING_ZEPHYR_H_ +#define NFC_TNEP_TAG_SIGNALLING_ZEPHYR_H_ + +#include +#include + +/** NFC TNEP library event count. */ +#define NFC_TNEP_EVENTS_NUMBER 2 + +/** @brief Initializes TNEP signalling using Zephyr primitives. + * + * @param[out] events Pointer to array of k_poll_event structures. + * @param[in] event_cnt Number of events in the array. + * Must be @ref NFC_TNEP_EVENTS_NUMBER. + * + * @retval 0 If the operation was successful. + * Otherwise, an (negative) error code is returned. + */ +int nfc_tnep_tag_signalling_init(struct k_poll_event *events, uint8_t event_cnt); + +#endif /* NFC_TNEP_TAG_SIGNALLING_ZEPHYR_H_ */ diff --git a/samples/bluetooth/peripheral_nfc_pairing/src/main.c b/samples/bluetooth/peripheral_nfc_pairing/src/main.c index e05510a03038..d00bc95691a6 100644 --- a/samples/bluetooth/peripheral_nfc_pairing/src/main.c +++ b/samples/bluetooth/peripheral_nfc_pairing/src/main.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -656,8 +657,13 @@ static void nfc_init(void) return; } - err = nfc_tnep_tag_init(events, NFC_TNEP_EVENTS_NUMBER, - nfc_t4t_ndef_rwpayload_set); + err = nfc_tnep_tag_signalling_init(events, NFC_TNEP_EVENTS_NUMBER); + if (err) { + printk("Cannot initialize tnep signalling, err: %d\n", err); + return; + } + + err = nfc_tnep_tag_init(nfc_t4t_ndef_rwpayload_set); if (err) { printk("Cannot initialize TNEP protocol, err: %d\n", err); return; diff --git a/samples/nfc/tnep_tag/src/main.c b/samples/nfc/tnep_tag/src/main.c index b175255c7294..c1e36f183acd 100644 --- a/samples/nfc/tnep_tag/src/main.c +++ b/samples/nfc/tnep_tag/src/main.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -209,8 +210,13 @@ int main(void) return 0; } - err = nfc_tnep_tag_init(events, ARRAY_SIZE(events), - nfc_t4t_ndef_rwpayload_set); + err = nfc_tnep_tag_signalling_init(events, ARRAY_SIZE(events)); + if (err) { + printk("Cannot initialize tnep signalling, err: %d\n", err); + return 0; + } + + err = nfc_tnep_tag_init(nfc_t4t_ndef_rwpayload_set); if (err) { printk("Cannot initialize TNEP protocol, err: %d\n", err); return 0; diff --git a/subsys/nfc/tnep/CMakeLists.txt b/subsys/nfc/tnep/CMakeLists.txt index e7ef201eee0b..151d1c50643d 100644 --- a/subsys/nfc/tnep/CMakeLists.txt +++ b/subsys/nfc/tnep/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_NFC_TNEP_TAG tag.c) +zephyr_library_sources_ifdef(CONFIG_NFC_TNEP_TAG_SIGNALLING_ZEPHYR tag_signalling_zephyr.c) zephyr_library_sources_ifdef(CONFIG_NFC_TNEP_POLLER poller.c) add_subdirectory_ifdef(CONFIG_NFC_TNEP_CH ch) diff --git a/subsys/nfc/tnep/Kconfig b/subsys/nfc/tnep/Kconfig index a5c4538076c6..f7901071e911 100644 --- a/subsys/nfc/tnep/Kconfig +++ b/subsys/nfc/tnep/Kconfig @@ -28,6 +28,15 @@ config NFC_TNEP_RX_MAX_RECORD_SIZE help Set the maximum size of received NDEF Record +choice NFC_TNEP_TAG_SIGNALLING + prompt "NFC TNEP Tag signalling method" + +config NFC_TNEP_TAG_SIGNALLING_ZEPHYR + bool "NFC TNEP Tag signalling using Zephyr primitives" + select POLL + +endchoice + module = NFC_TNEP_TAG module-str = TNEP_TAG source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config" diff --git a/subsys/nfc/tnep/tag.c b/subsys/nfc/tnep/tag.c index b8f30b6ffbaf..1b99c228c3de 100644 --- a/subsys/nfc/tnep/tag.c +++ b/subsys/nfc/tnep/tag.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -14,15 +15,6 @@ LOG_MODULE_REGISTER(nfc_tnep_tag, CONFIG_NFC_TNEP_TAG_LOG_LEVEL); -#define TNEP_EVENT_RX_IDX 0 -#define TNEP_EVENT_TX_IDX 1 - -enum tnep_event { - TNEP_EVENT_DUMMY, - TNEP_EVENT_MSG_RX_NEW, - TNEP_EVENT_TAG_SELECTED, -}; - enum tnep_state_name { TNEP_STATE_DISABLED, TNEP_STATE_SERVICE_READY, @@ -53,12 +45,6 @@ struct tnep_rx_buffer { size_t len; }; -struct tnep_control { - struct k_poll_event *events; - struct k_poll_signal msg_rx; - struct k_poll_signal msg_tx; -}; - struct tnep_tag { struct nfc_ndef_msg_desc *msg; struct tnep_buffer tx; @@ -72,7 +58,6 @@ struct tnep_tag { uint8_t *current_buff; }; -static struct tnep_control tnep_ctrl; static struct tnep_tag tnep; struct tnep_state { @@ -501,11 +486,10 @@ void nfc_tnep_tag_rx_msg_indicate(const uint8_t *rx_buffer, size_t len) tnep.rx.len = len; tnep.rx.data = rx_buffer; - k_poll_signal_raise(&tnep_ctrl.msg_rx, TNEP_EVENT_MSG_RX_NEW); + nfc_tnep_tag_signalling_rx_event_raise(TNEP_EVENT_MSG_RX_NEW); } -int nfc_tnep_tag_init(struct k_poll_event *events, uint8_t event_cnt, - nfc_payload_set_t payload_set) +int nfc_tnep_tag_init(nfc_payload_set_t payload_set) { extern struct nfc_tnep_tag_service _nfc_tnep_tag_service_list_start[]; @@ -514,21 +498,11 @@ int nfc_tnep_tag_init(struct k_poll_event *events, uint8_t event_cnt, LOG_DBG("TNEP initialization"); - if (!events) { - return -EINVAL; - } - if (!payload_set) { LOG_ERR("No function for NFC payload set provided"); return -EINVAL; } - if (event_cnt != NFC_TNEP_EVENTS_NUMBER) { - LOG_ERR("Invalid k_pool events count. Got %d events, required %d", - event_cnt, NFC_TNEP_EVENTS_NUMBER); - return -EINVAL; - } - if (!atomic_cas(¤t_state, TNEP_STATE_DISABLED, TNEP_STATE_DISABLED)) { LOG_ERR("TNEP already running"); @@ -541,25 +515,11 @@ int nfc_tnep_tag_init(struct k_poll_event *events, uint8_t event_cnt, return -EIO; } - tnep_ctrl.events = events; tnep.current_buff = tnep.tx.data; tnep.data_set = payload_set; tnep.svc_cnt = _nfc_tnep_tag_service_list_end - _nfc_tnep_tag_service_list_start; - LOG_DBG("k_pool signals initialization"); - - k_poll_signal_init(&tnep_ctrl.msg_rx); - k_poll_signal_init(&tnep_ctrl.msg_tx); - - k_poll_event_init(&tnep_ctrl.events[TNEP_EVENT_RX_IDX], - K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, - &tnep_ctrl.msg_rx); - - k_poll_event_init(&tnep_ctrl.events[TNEP_EVENT_TX_IDX], - K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, - &tnep_ctrl.msg_tx); - return 0; } @@ -635,19 +595,16 @@ int nfc_tnep_initial_msg_encode(struct nfc_ndef_msg_desc *msg, void nfc_tnep_tag_process(void) { - /* Check for signals */ - for (size_t i = 0; i < NFC_TNEP_EVENTS_NUMBER; i++) { - if (tnep_ctrl.events[i].state == K_POLL_STATE_SIGNALED) { - enum tnep_event event; - - event = tnep_ctrl.events[i].signal->result; + enum tnep_event event = TNEP_EVENT_DUMMY; - k_poll_signal_reset(tnep_ctrl.events[i].signal); - tnep_ctrl.events[i].state = K_POLL_STATE_NOT_READY; + if (nfc_tnep_tag_signalling_rx_event_check_and_clear(&event)) { + /* Run TNEP State Machine - prepare response */ + tnep_state_machine[atomic_get(¤t_state)].process(event); + } - /* Run TNEP State Machine - prepare response */ - tnep_state_machine[atomic_get(¤t_state)].process(event); - } + if (nfc_tnep_tag_signalling_tx_event_check_and_clear(&event)) { + /* Run TNEP State Machine - prepare response */ + tnep_state_machine[atomic_get(¤t_state)].process(event); } } @@ -707,7 +664,7 @@ int nfc_tnep_tag_tx_msg_no_app_data(void) void nfc_tnep_tag_on_selected(void) { - k_poll_signal_raise(&tnep_ctrl.msg_tx, TNEP_EVENT_TAG_SELECTED); + nfc_tnep_tag_signalling_tx_event_raise(TNEP_EVENT_TAG_SELECTED); } size_t nfc_tnep_tag_svc_count_get(void) diff --git a/subsys/nfc/tnep/tag_signalling_zephyr.c b/subsys/nfc/tnep/tag_signalling_zephyr.c new file mode 100644 index 000000000000..028beb874396 --- /dev/null +++ b/subsys/nfc/tnep/tag_signalling_zephyr.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(nfc_tnep_tag, CONFIG_NFC_TNEP_TAG_LOG_LEVEL); + +#define TNEP_EVENT_RX_IDX 0 +#define TNEP_EVENT_TX_IDX 1 + +struct tnep_control { + struct k_poll_event *events; + struct k_poll_signal msg_rx; + struct k_poll_signal msg_tx; +}; + +static struct tnep_control tnep_ctrl; + +int nfc_tnep_tag_signalling_init(struct k_poll_event *events, uint8_t event_cnt) +{ + if (!events) { + return -EINVAL; + } + + if (event_cnt != NFC_TNEP_EVENTS_NUMBER) { + LOG_ERR("Invalid k_pool events count. Got %d events, required %d", + event_cnt, NFC_TNEP_EVENTS_NUMBER); + return -EINVAL; + } + + tnep_ctrl.events = events; + + k_poll_signal_init(&tnep_ctrl.msg_rx); + k_poll_signal_init(&tnep_ctrl.msg_tx); + + k_poll_event_init(&tnep_ctrl.events[TNEP_EVENT_RX_IDX], + K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, + &tnep_ctrl.msg_rx); + + k_poll_event_init(&tnep_ctrl.events[TNEP_EVENT_TX_IDX], + K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, + &tnep_ctrl.msg_tx); + + return 0; +} + +void nfc_tnep_tag_signalling_rx_event_raise(enum tnep_event event) +{ + k_poll_signal_raise(&tnep_ctrl.msg_rx, event); +} + +void nfc_tnep_tag_signalling_tx_event_raise(enum tnep_event event) +{ + k_poll_signal_raise(&tnep_ctrl.msg_tx, event); +} + +static bool event_check_and_clear(int event_idx, enum tnep_event *event) +{ + if (tnep_ctrl.events[event_idx].state == K_POLL_STATE_SIGNALED) { + *event = tnep_ctrl.events[event_idx].signal->result; + + k_poll_signal_reset(tnep_ctrl.events[event_idx].signal); + tnep_ctrl.events[event_idx].state = K_POLL_STATE_NOT_READY; + + return true; + } + + return false; +} + +bool nfc_tnep_tag_signalling_rx_event_check_and_clear(enum tnep_event *event) +{ + return event_check_and_clear(TNEP_EVENT_RX_IDX, event); +} + +bool nfc_tnep_tag_signalling_tx_event_check_and_clear(enum tnep_event *event) +{ + return event_check_and_clear(TNEP_EVENT_TX_IDX, event); +}