diff --git a/core/embed/io/nfc/inc/io/nfc.h b/core/embed/io/nfc/inc/io/nfc.h
index d516a12fff..72bed61937 100644
--- a/core/embed/io/nfc/inc/io/nfc.h
+++ b/core/embed/io/nfc/inc/io/nfc.h
@@ -17,12 +17,10 @@
* along with this program. If not, see .
*/
-#ifndef TREZORHAL_NFC_H
-#define TREZORHAL_NFC_H
-#include
-#include
-#include "ndef.h"
+#pragma once
+
+#include "trezor_types.h"
#define NFC_MAX_UID_LEN 10
@@ -46,7 +44,7 @@ typedef enum {
} nfc_dev_type_t;
typedef enum {
- NFC_STATE_IDLE,
+ NFC_NO_EVENT,
NFC_STATE_ACTIVATED,
} nfc_event_t;
@@ -60,45 +58,40 @@ typedef enum {
typedef struct {
uint8_t type;
- char uid[NFC_MAX_UID_LEN];
+ char uid[NFC_MAX_UID_LEN + 1]; // Plus one for string termination
uint8_t uid_len;
} nfc_dev_info_t;
-// Initialize NFC driver including supportive RFAL middlewere
-nfc_status_t nfc_init();
+// Initialize NFC driver including supportive RFAL middleware
+nfc_status_t nfc_init(void);
-// Deinitialize NFC drive
-nfc_status_t nfc_deinit();
+// Deinitialize NFC driver
+nfc_status_t nfc_deinit(void);
// Register NFC technology (or several) to be explored by NFC state machine
// use this function before activating the state machine with nfc_activate_stm()
-nfc_status_t nfc_register_tech(nfc_tech_t tech);
+nfc_status_t nfc_register_tech(const nfc_tech_t tech);
-// Register event callbacks to be called with state machine, this function is
-// used when user need to further interact (read/write) with the connected NFC
-// device
-nfc_status_t nfc_register_event_callback(nfc_event_t event_type,
- void (*cb_fn)(void));
-
-// Activate the NFC RFAL state machine which will explore the registered
-// technologies State machine handles the low level NFC protocols of registered
-// technologies and provide the user with the activated device information. With
-// activated, user have to constantly run NFC workerwith nfc_feed_worker() to
-// activly loop the state machine.
-nfc_status_t nfc_activate_stm();
+// Activates the NFC RFAL state machine to explore the previously registered technologies.
+// The RFAL handles low-level NFC protocols and provides information about the activated device.
+// This function only starts the exploration; you must regularly call nfc_get_event() to continue
+// processing NFC operations.
+nfc_status_t nfc_activate_stm(void);
// Deactivate the NFC RFAL state machine (put in IDLE state).
-nfc_status_t nfc_deactivate_stm();
+nfc_status_t nfc_deactivate_stm(void);
-// Calls NFC RFAL worker which service the NFC statemachine exploring the
-// registered technologies. this function has to be actively called in loop
-// (main NFC poll function).
-nfc_status_t nfc_feed_worker();
+// Calls NFC RFAL worker to service the NFC state machine and expolore
+// registered technologies. This function has to be actively called in loop
+// (main NFC poll function), returns nfc event.
+nfc_event_t nfc_get_event(void);
+
+// Deactivate the currently activated NFC device and put RFAL state machine back to
+// discovary state.
+nfc_status_t nfc_dev_deactivate(void);
// Read the general device information of the activated NFC device.
nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info);
-// Write the NDFE message with the trezor.io URI to the activated NFC device.
-nfc_status_t nfc_def_write_ndef_uri();
-
-#endif // TREZORHAL_NFC_H
+// Write the NDEF message with the trezor.io URI to the activated NFC device.
+nfc_status_t nfc_dev_write_ndef_uri(void);
diff --git a/core/embed/io/nfc/rfal/LOCAL_CHANGES.md b/core/embed/io/nfc/rfal/LOCAL_CHANGES.md
new file mode 100644
index 0000000000..394d73e6a0
--- /dev/null
+++ b/core/embed/io/nfc/rfal/LOCAL_CHANGES.md
@@ -0,0 +1,8 @@
+
+RFAL middleware was imported into trezor-firmware to support a low level NFC operations of st25r3916b from
+https://www.st.com/en/embedded-software/stsw-st25r-lib.html#overview (version 1.7.0)
+
+# Local changes
+
+1. rfalIsoDepInfo structure defined in include/rfal_isoDep.h and rfalNfcDepInfo include/rfal_nfcDep.h contains variable DSI which colide with the DSI macro in
+STM32 HAL drivers. To resolve this, variale in RFAL library was refactored to DSI_ID.
\ No newline at end of file
diff --git a/core/embed/io/nfc/st25r3916b/card_emulation.c b/core/embed/io/nfc/st25r3916b/card_emulation.c
index 983ee1737b..cb92e73010 100644
--- a/core/embed/io/nfc/st25r3916b/card_emulation.c
+++ b/core/embed/io/nfc/st25r3916b/card_emulation.c
@@ -529,7 +529,7 @@ static uint16_t card_emulation_t3t_update(uint8_t *cmdData, uint8_t *rspData) {
* @return None
*****************************************************************************
*/
-void card_emulation_init(uint8_t *nfcfNfcid) {
+void card_emulation_init(const uint8_t *nfcfNfcid) {
if (nfcfNfcid != NULL) {
memcpy(gNfcfNfcid, nfcfNfcid, RFAL_NFCF_NFCID2_LEN);
}
diff --git a/core/embed/io/nfc/st25r3916b/card_emulation.h b/core/embed/io/nfc/st25r3916b/card_emulation.h
index d747d0b37a..f175e3ab4c 100644
--- a/core/embed/io/nfc/st25r3916b/card_emulation.h
+++ b/core/embed/io/nfc/st25r3916b/card_emulation.h
@@ -16,16 +16,14 @@
*/
/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef DEMO_CE_H
-#define DEMO_CE_H
+#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
-#include
-#include
+#include
/** @addtogroup X-CUBE-NFC6_Applications
* @brief Sample applications for X-NUCLEO-NFC06A1 STM32 expansion boards.
@@ -74,7 +72,7 @@ extern "C" {
/** @defgroup CE_CardEmul_Exported_functions
* @{
*/
-void card_emulation_init(uint8_t *nfcfNfcid);
+void card_emulation_init(const uint8_t *nfcfNfcid);
uint16_t card_emulation_t3t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
uint16_t txBufLen);
uint16_t card_emulation_t4t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
@@ -100,6 +98,4 @@ uint16_t card_emulation_t4t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
}
#endif
-#endif /* DEMO_CE_H */
-
/******************* (C) COPYRIGHT 2018 STMicroelectronics *****END OF FILE****/
diff --git a/core/embed/io/nfc/st25r3916b/ndef.c b/core/embed/io/nfc/st25r3916b/ndef.c
index d656fcc282..0a30342f55 100644
--- a/core/embed/io/nfc/st25r3916b/ndef.c
+++ b/core/embed/io/nfc/st25r3916b/ndef.c
@@ -1,12 +1,28 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
-
+#include
#include "ndef.h"
-#include
-#include
// ndef_status_t create_ndef_record_uri(uint8_t *bytearray, )
-ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
+ndef_status_t ndef_parse_message(const uint8_t *buffer, uint16_t buffer_len,
ndef_message_t *message) {
memset(message, 0, sizeof(ndef_message_t));
@@ -34,7 +50,7 @@ ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
remaining_len = message->message_total_len;
while (1) {
- parse_ndef_record(buffer, remaining_len,
+ ndef_parse_record(buffer, remaining_len,
&(message->records[message->records_cnt]));
buffer += message->records[message->records_cnt].record_total_len;
remaining_len -= message->records[message->records_cnt].record_total_len;
@@ -57,7 +73,7 @@ ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
return NDEF_OK;
}
-ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
+ndef_status_t ndef_parse_record(const uint8_t *buffer, uint16_t len,
ndef_record_t *rec) {
uint8_t bp = 0;
@@ -119,7 +135,7 @@ ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
return NDEF_OK;
}
-uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
+uint16_t ndef_create_uri(const char *uri, uint8_t *buffer) {
*buffer = 0x3; // TLV header
buffer++;
@@ -129,15 +145,6 @@ uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
*buffer = uri_len + 5; // uri + record header;
buffer++;
- // ndef_record_header_t hdr = {
- // .tnf = 0x01,
- // .il = 0,
- // .sr = 1,
- // .cf = 0,
- // .me = 1,
- // .mb = 1,
- // };
-
*buffer = 0xD1; // NDEF record Header
buffer++;
@@ -158,8 +165,6 @@ uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
buffer++;
}
- // memcpy(buffer, uri, uri_len);
-
*buffer = 0xFE; // TLV termination
return uri_len + 7; // return buffer len
diff --git a/core/embed/io/nfc/st25r3916b/ndef.h b/core/embed/io/nfc/st25r3916b/ndef.h
index f68f6eeff7..cef1899580 100644
--- a/core/embed/io/nfc/st25r3916b/ndef.h
+++ b/core/embed/io/nfc/st25r3916b/ndef.h
@@ -1,7 +1,6 @@
-#include
+#pragma once
-#ifndef NDEF_H
-#define NDEF_H
+#include
#define NDEF_MAX_RECORDS 3
#define NDEF_MAX_RECORD_PAYLOAD_BYTES 50
@@ -37,10 +36,9 @@ typedef struct {
ndef_record_t records[NDEF_MAX_RECORDS];
} ndef_message_t;
-ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
+ndef_status_t ndef_parse_message(const uint8_t *buffer, uint16_t buffer_len,
ndef_message_t *message);
-ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
+ndef_status_t ndef_parse_record(const uint8_t *buffer, uint16_t len,
ndef_record_t *rec);
-uint16_t create_ndef_uri(const char *uri, uint8_t *buffer);
+uint16_t ndef_create_uri(const char *uri, uint8_t *buffer);
-#endif
diff --git a/core/embed/io/nfc/st25r3916b/nfc.c b/core/embed/io/nfc/st25r3916b/nfc.c
index 4ecdffa954..7bd708bebb 100644
--- a/core/embed/io/nfc/st25r3916b/nfc.c
+++ b/core/embed/io/nfc/st25r3916b/nfc.c
@@ -1,23 +1,52 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
-#include
-#include
#include
#include
-#include "../inc/io/nfc.h"
+#include
+#include
+#include
+
+#include "io/nfc.h"
+#include "rfal_isoDep.h"
+#include "rfal_nfc.h"
+#include "rfal_nfca.h"
+#include "rfal_rf.h"
+#include "rfal_t2t.h"
+#include "rfal_utils.h"
#include "card_emulation.h"
#include "ndef.h"
#include "nfc_internal.h"
#include "rfal_platform.h"
-#include "../rfal/include/rfal_isoDep.h"
-#include "../rfal/include/rfal_nfc.h"
-#include "../rfal/include/rfal_nfca.h"
-#include "../rfal/include/rfal_rf.h"
-#include "../rfal/include/rfal_t2t.h"
-#include "../rfal/include/rfal_utils.h"
-
-#include "stm32u5xx_hal.h"
+#define LM_SEL_RES \
+ 0x20U /*!hspi), 0, sizeof(drv->hspi));
- drv->hspi.Instance = SPI_INSTANCE_3;
+ drv->hspi.Instance = NFC_SPI_INSTANCE;
drv->hspi.Init.Mode = SPI_MODE_MASTER;
drv->hspi.Init.BaudRatePrescaler =
SPI_BAUDRATEPRESCALER_32; // TODO: Calculate frequency precisly.
@@ -204,7 +213,7 @@ nfc_status_t nfc_init() {
return NFC_OK;
}
-nfc_status_t nfc_deinit() {
+nfc_status_t nfc_deinit(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
if (!drv->initialized) {
@@ -228,40 +237,25 @@ nfc_status_t nfc_deinit() {
HAL_SPI_DeInit(&(drv->hspi));
- HAL_GPIO_DeInit(SPI_INSTANCE_3_MISO_PORT, SPI_INSTANCE_3_MISO_PIN);
- HAL_GPIO_DeInit(SPI_INSTANCE_3_MOSI_PORT, SPI_INSTANCE_3_MOSI_PIN);
- HAL_GPIO_DeInit(SPI_INSTANCE_3_SCK_PORT, SPI_INSTANCE_3_SCK_PIN);
- HAL_GPIO_DeInit(SPI_INSTANCE_3_NSS_PORT, SPI_INSTANCE_3_NSS_PIN);
+ HAL_GPIO_DeInit(NFC_SPI_MISO_PORT, NFC_SPI_MISO_PIN);
+ HAL_GPIO_DeInit(NFC_SPI_MOSI_PORT, NFC_SPI_MOSI_PIN);
+ HAL_GPIO_DeInit(NFC_SPI_SCK_PORT, NFC_SPI_SCK_PIN);
+ HAL_GPIO_DeInit(NFC_SPI_NSS_PORT, NFC_SPI_NSS_PIN);
HAL_GPIO_DeInit(NFC_INT_PORT, NFC_INT_PIN);
drv->initialized = false;
return NFC_OK;
+
}
-void rfal_callback(rfalNfcState st) {
+
+nfc_status_t nfc_register_tech(const nfc_tech_t tech) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
- switch (st) {
- case RFAL_NFC_STATE_IDLE:
- if (drv->nfc_state_idle_cb != NULL) {
- drv->nfc_state_idle_cb();
- }
- break;
-
- case RFAL_NFC_STATE_ACTIVATED:
- if (drv->nfc_state_activated_cb != NULL) {
- drv->nfc_state_activated_cb();
- }
- break;
- default:
- // State not reported
- break;
+ if (drv->initialized == false) {
+ return NFC_NOT_INITIALIZED;
}
-}
-
-nfc_status_t nfc_register_tech(nfc_tech_t tech) {
- st25r3916b_driver_t *drv = &g_st25r3916b_driver;
drv->disc_params.devLimit = 1;
memcpy(&drv->disc_params.nfcid3, NFCID3, sizeof(NFCID3));
@@ -269,11 +263,6 @@ nfc_status_t nfc_register_tech(nfc_tech_t tech) {
drv->disc_params.GBLen = sizeof(GB);
drv->disc_params.p2pNfcaPrio = true;
drv->disc_params.totalDuration = 1000U;
- drv->disc_params.notifyCb = rfal_callback;
-
- if (drv->initialized == false) {
- return NFC_NOT_INITIALIZED;
- }
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
return NFC_ERROR;
@@ -324,34 +313,13 @@ nfc_status_t nfc_register_tech(nfc_tech_t tech) {
return NFC_OK;
}
-nfc_status_t nfc_register_event_callback(nfc_event_t event_type,
- void (*cb_fn)(void)) {
+nfc_status_t nfc_activate_stm(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
- switch (event_type) {
- case NFC_STATE_IDLE:
- drv->nfc_state_idle_cb = cb_fn;
- break;
- case NFC_STATE_ACTIVATED:
- drv->nfc_state_activated_cb = cb_fn;
- break;
- default:
- return NFC_ERROR;
+ if(!drv->initialized) {
+ return NFC_NOT_INITIALIZED;
}
- return NFC_OK;
-}
-
-nfc_status_t nfc_unregister_event_callback() {
- st25r3916b_driver_t *drv = &g_st25r3916b_driver;
- drv->disc_params.notifyCb = NULL;
-
- return NFC_OK;
-}
-
-nfc_status_t nfc_activate_stm() {
- st25r3916b_driver_t *drv = &g_st25r3916b_driver;
-
ReturnCode err;
err = rfalNfcDiscover(&(drv->disc_params));
if (err != RFAL_ERR_NONE) {
@@ -361,7 +329,14 @@ nfc_status_t nfc_activate_stm() {
return NFC_OK;
}
-nfc_status_t nfc_deactivate_stm() {
+nfc_status_t nfc_deactivate_stm(void) {
+
+ st25r3916b_driver_t *drv = &g_st25r3916b_driver;
+
+ if(!drv->initialized) {
+ return NFC_OK;
+ }
+
// In case the NFC state machine is active, deactivate to idle before
// registering a new card emulation technology.
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
@@ -374,61 +349,60 @@ nfc_status_t nfc_deactivate_stm() {
return NFC_OK;
}
-nfc_status_t nfc_feed_worker() {
+nfc_event_t nfc_get_event(void) {
+
+ st25r3916b_driver_t *drv = &g_st25r3916b_driver;
+
+ if(!drv->initialized) {
+ return NFC_NOT_INITIALIZED;
+ }
+
static rfalNfcDevice *nfcDevice;
rfalNfcWorker(); /* Run RFAL worker periodically */
- if (rfalNfcIsDevActivated(rfalNfcGetState())) {
+ if(rfalNfcIsDevActivated(rfalNfcGetState())) {
+
rfalNfcGetActiveDevice(&nfcDevice);
+ // Perform immediate mandatory actions for certain technology (Placeholder)
switch (nfcDevice->type) {
- /*******************************************************************************/
+
case RFAL_NFC_LISTEN_TYPE_NFCA:
switch (nfcDevice->dev.nfca.type) {
case RFAL_NFCA_T1T:
break;
-
case RFAL_NFCA_T4T:
break;
-
case RFAL_NFCA_T4T_NFCDEP:
+ break;
case RFAL_NFCA_NFCDEP:
break;
default:
break;
}
- /*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCB:
break;
- /*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCF:
break;
- /*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCV:
break;
- /*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_ST25TB:
break;
- /*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_AP2P:
case RFAL_NFC_POLL_TYPE_AP2P:
break;
- /*******************************************************************************/
-
- /*******************************************************************************/
-
- // Card emulators need to promptly respond to the reader commands, so when
- // activated rfal worker is called seveal times untill back to back
- // communication with the reader is completed. This may prolong the
- // run_feed_worker service time compared to standard reader mode.
+ // Card emulators must respond to reader commands promptly. Once activated,
+ // the RFAL worker is called multiple times until back-to-back communication
+ // with the reader finishes. This can prolong the nfc_get_event() service
+ // time compared to standard reader mode.
case RFAL_NFC_POLL_TYPE_NFCA:
case RFAL_NFC_POLL_TYPE_NFCF:
@@ -436,59 +410,35 @@ nfc_status_t nfc_feed_worker() {
// not supported yet
} else {
nfc_card_emulator_loop(nfcDevice);
+ rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY); // Automatically deactivate
}
- break;
+
+ return NFC_NO_EVENT;
break;
- break;
- /*******************************************************************************/
default:
break;
}
- rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY);
+ return NFC_STATE_ACTIVATED;
+
}
- return NFC_OK;
+ return NFC_NO_EVENT;
}
-static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev) {
- ReturnCode err = RFAL_ERR_INTERNAL;
- uint8_t *rxData;
- uint16_t *rcvLen;
- uint8_t txBuf[150];
- uint16_t txLen;
+nfc_status_t nfc_dev_deactivate(void) {
- do {
- rfalNfcWorker();
+ st25r3916b_driver_t drv = g_st25r3916b_driver;
- switch (rfalNfcGetState()) {
- case RFAL_NFC_STATE_ACTIVATED:
- err = nfc_transcieve_blocking(NULL, 0, &rxData, &rcvLen, 0);
- break;
+ if (!drv.initialized) {
+ return NFC_NOT_INITIALIZED;
+ }
- case RFAL_NFC_STATE_DATAEXCHANGE:
- case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
+ rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY);
- txLen = ((nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA)
- ? card_emulation_t4t(rxData, *rcvLen, txBuf, sizeof(txBuf))
- : rfalConvBytesToBits(card_emulation_t3t(
- rxData, rfalConvBitsToBytes(*rcvLen), txBuf,
- sizeof(txBuf))));
-
- err = nfc_transcieve_blocking(txBuf, txLen, &rxData, &rcvLen,
- RFAL_FWT_NONE);
- break;
-
- case RFAL_NFC_STATE_START_DISCOVERY:
- return;
-
- case RFAL_NFC_STATE_LISTEN_SLEEP:
- default:
- break;
- }
- } while ((err == RFAL_ERR_NONE) || (err == RFAL_ERR_SLEEP_REQ));
+ return NFC_OK;
}
nfc_status_t nfc_transceive(const uint8_t *txData, uint16_t txDataLen,
@@ -514,11 +464,18 @@ nfc_status_t nfc_transceive(const uint8_t *txData, uint16_t txDataLen,
return NFC_OK;
}
-nfc_status_t nfc_def_write_ndef_uri() {
+nfc_status_t nfc_dev_write_ndef_uri(void) {
+
+ st25r3916b_driver_t *drv = &g_st25r3916b_driver;
+
+ if (!drv->initialized) {
+ return NFC_NOT_INITIALIZED;
+ }
+
// NDEF message
uint8_t ndef_message[128] = {0};
- uint16_t buffer_len = create_ndef_uri("trezor.io/", ndef_message);
+ uint16_t buffer_len = ndef_create_uri("trezor.io/", ndef_message);
for (uint8_t i = 0; i < buffer_len / 4; i++) {
rfalT2TPollerWrite(4 + i, ndef_message + i * 4);
@@ -564,8 +521,12 @@ nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info) {
return NFC_ERROR;
}
- char *uid_str = hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen);
- memcpy(dev_info->uid, uid_str, nfcDevice->nfcidLen);
+ if (nfcDevice->nfcidLen <= NFC_MAX_UID_LEN) {
+ return NFC_ERROR;
+ }
+
+ // Copy the hex UID in printable string
+ cstr_encode_hex(dev_info->uid, NFC_MAX_UID_LEN, nfcDevice->nfcid, nfcDevice->nfcidLen);
} else {
// No device activated
@@ -575,58 +536,6 @@ nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info) {
return NFC_OK;
}
-// static void parse_tag_header(uint8_t *data, uint16_t dataLen) {
-// nfc_device_header_t2t_t hdr;
-
-// memcpy(hdr.UID, data, 3);
-// hdr.BCC[0] = data[3];
-// memcpy(hdr.UID + 3, data + 4, 4);
-// memcpy(hdr.SYSTEM_AREA, data + 8, 2);
-// memcpy(hdr.CC, data + 12, 4);
-
-// }
-
-static ReturnCode nfc_transcieve_blocking(uint8_t *txBuf, uint16_t txBufSize,
- uint8_t **rxData, uint16_t **rcvLen,
- uint32_t fwt) {
- ReturnCode err;
-
- err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxData, rcvLen, fwt);
- if (err == RFAL_ERR_NONE) {
- do {
- rfalNfcWorker();
- err = rfalNfcDataExchangeGetStatus();
- } while (err == RFAL_ERR_BUSY);
- }
- return err;
-}
-
-static char *hex2Str(unsigned char *data, size_t dataLen) {
- {
- unsigned char *pin = data;
- const char *hex = "0123456789ABCDEF";
- char *pout = hexStr[hexStrIdx];
- uint8_t i = 0;
- uint8_t idx = hexStrIdx;
- if (dataLen == 0) {
- pout[0] = 0;
- } else {
- for (; i < dataLen - 1; ++i) {
- *pout++ = hex[(*pin >> 4) & 0xF];
- *pout++ = hex[(*pin++) & 0xF];
- }
- *pout++ = hex[(*pin >> 4) & 0xF];
- *pout++ = hex[(*pin) & 0xF];
- *pout = 0;
- }
-
- hexStrIdx++;
- hexStrIdx %= MAX_HEX_STR;
-
- return hexStr[idx];
- }
-}
-
HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint8_t *rxData, uint16_t length) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@@ -644,22 +553,9 @@ HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
return status;
}
-uint32_t nfc_create_timer(uint16_t time) { return (systick_ms() + time); }
+uint32_t nfc_create_timer(uint16_t time) { return ticks_timeout(time); }
-bool nfc_timer_is_expired(uint32_t timer) {
- uint32_t u_diff;
- int32_t s_diff;
-
- u_diff = (timer - systick_ms()); // Calculate the diff between the timers
- s_diff = u_diff; // Convert the diff to a signed var
-
- // Check if the given timer has expired already
- if (s_diff < 0) {
- return true;
- }
-
- return false;
-}
+bool nfc_timer_is_expired(uint32_t timer) { return ticks_expired(timer); }
void nfc_ext_irq_set_callback(void (*cb)(void)) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@@ -675,3 +571,58 @@ void NFC_EXTI_INTERRUPT_HANDLER(void) {
drv->nfc_irq_callback();
}
}
+
+
+static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev) {
+
+ ReturnCode err = RFAL_ERR_INTERNAL;
+ uint8_t *rxBuf;
+ uint16_t *rcvLen;
+ uint8_t txBuf[150];
+ uint16_t txLen;
+
+ do {
+ rfalNfcWorker();
+
+ switch (rfalNfcGetState()) {
+ case RFAL_NFC_STATE_ACTIVATED:
+ err = nfc_transcieve_blocking(NULL, 0, &rxBuf, &rcvLen, 0);
+ break;
+
+ case RFAL_NFC_STATE_DATAEXCHANGE:
+ case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
+
+ txLen = ((nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA)
+ ? card_emulation_t4t(rxBuf, *rcvLen, txBuf, sizeof(txBuf))
+ : rfalConvBytesToBits(card_emulation_t3t(
+ rxBuf, rfalConvBitsToBytes(*rcvLen), txBuf,
+ sizeof(txBuf))));
+
+ err = nfc_transcieve_blocking(txBuf, txLen, &rxBuf, &rcvLen,
+ RFAL_FWT_NONE);
+ break;
+
+ case RFAL_NFC_STATE_START_DISCOVERY:
+ return;
+
+ case RFAL_NFC_STATE_LISTEN_SLEEP:
+ default:
+ break;
+ }
+ } while ((err == RFAL_ERR_NONE) || (err == RFAL_ERR_SLEEP_REQ));
+}
+
+static ReturnCode nfc_transcieve_blocking(uint8_t *txBuf, uint16_t txBufSize,
+ uint8_t **rxBuf, uint16_t **rcvLen,
+ uint32_t fwt) {
+ ReturnCode err;
+
+ err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxBuf, rcvLen, fwt);
+ if (err == RFAL_ERR_NONE) {
+ do {
+ rfalNfcWorker();
+ err = rfalNfcDataExchangeGetStatus();
+ } while (err == RFAL_ERR_BUSY);
+ }
+ return err;
+}
\ No newline at end of file
diff --git a/core/embed/io/nfc/st25r3916b/nfc_internal.h b/core/embed/io/nfc/st25r3916b/nfc_internal.h
index 579a786efa..7dd5e1bdb9 100644
--- a/core/embed/io/nfc/st25r3916b/nfc_internal.h
+++ b/core/embed/io/nfc/st25r3916b/nfc_internal.h
@@ -1,9 +1,8 @@
+#pragma once
+
#include
-#ifndef TREZORHAL_NFC_INTERNAL_H
-#define TREZORHAL_NFC_INTERNAL_H
-
HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint8_t *rxData, uint16_t length);
@@ -13,4 +12,3 @@ bool nfc_timer_is_expired(uint32_t timer);
void nfc_ext_irq_set_callback(void (*cb)(void));
-#endif
diff --git a/core/embed/io/nfc/st25r3916b/rfal_platform.h b/core/embed/io/nfc/st25r3916b/rfal_platform.h
index d410e93001..8995a7e427 100644
--- a/core/embed/io/nfc/st25r3916b/rfal_platform.h
+++ b/core/embed/io/nfc/st25r3916b/rfal_platform.h
@@ -20,8 +20,7 @@
*
*/
-#ifndef RFAL_PLATFORM_H
-#define RFAL_PLATFORM_H
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -34,16 +33,13 @@ extern "C" {
*/
#include
-#include "stm32u5xx_hal.h"
-
+#include
#include
#include
-#include
-#include
-#include
-#include
+#include
#include "io/nfc.h"
+
#include "nfc_internal.h"
/*
@@ -56,10 +52,10 @@ extern "C" {
#define ST25R3916B
// GPIO pin used for ST25R SPI SS
-#define ST25R_SS_PIN SPI_INSTANCE_3_NSS_PIN
+#define ST25R_SS_PIN NFC_SPI_NSS_PIN
// GPIO port used for ST25R SPI SS port
-#define ST25R_SS_PORT SPI_INSTANCE_3_NSS_PORT
+#define ST25R_SS_PORT NFC_SPI_NSS_PORT
// GPIO pin used for ST25R External Interrupt
#define ST25R_INT_PIN NFC_INT_PIN
@@ -73,12 +69,10 @@ extern "C" {
******************************************************************************
*/
#define platformProtectST25RComm() \
- NVIC_DisableIRQ(EXTI10_IRQn) // TODO: PRobably should be irq_lock instead //
- // Protect the unique access to communication
- // channel (disable IRQ on single thread)
+ NVIC_DisableIRQ(NFC_EXTI_INTERRUPT_NUM)
#define platformUnprotectST25RComm() \
- NVIC_EnableIRQ(EXTI10_IRQn) // TODO: Use macro here /
+ NVIC_EnableIRQ(NFC_EXTI_INTERRUPT_NUM)
#define platformProtectST25RIrqStatus() \
platformProtectST25RComm() /*!< Protect unique access to IRQ status var - \
@@ -292,5 +286,3 @@ extern uint8_t globalCommProtectCnt; /* Global Protection Counter provided per
#ifdef __cplusplus
}
#endif
-
-#endif /* RFAL_PLATFORM_H */
diff --git a/core/embed/models/T3W1/boards/trezor_t3w1_revA.h b/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
index c30a55d4e3..8745d8f906 100644
--- a/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
+++ b/core/embed/models/T3W1/boards/trezor_t3w1_revA.h
@@ -166,22 +166,24 @@
#define NRF_OUT_FW_RUNNING_PORT GPIOE
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
-#define SPI_INSTANCE_3 SPI3
-#define SPI_INSTANCE_3_PIN_AF GPIO_AF6_SPI3
-#define SPI_INSTANCE_3_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
-#define SPI_INSTANCE_3_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
-#define SPI_INSTANCE_3_MISO_PORT GPIOB
-#define SPI_INSTANCE_3_MISO_PIN GPIO_PIN_4
-#define SPI_INSTANCE_3_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
-#define SPI_INSTANCE_3_MOSI_PORT GPIOB
-#define SPI_INSTANCE_3_MOSI_PIN GPIO_PIN_5
-#define SPI_INSTANCE_3_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
-#define SPI_INSTANCE_3_SCK_PORT GPIOG
-#define SPI_INSTANCE_3_SCK_PIN GPIO_PIN_9
-#define SPI_INSTANCE_3_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
-#define SPI_INSTANCE_3_NSS_PORT GPIOG
-#define SPI_INSTANCE_3_NSS_PIN GPIO_PIN_12
-#define SPI_INSTANCE_3_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
+#define NFC_SPI_INSTANCE SPI3
+#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
+#define NFC_SPI_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
+#define NFC_SPI_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
+#define NFC_SPI_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET
+#define NFC_SPI_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET
+#define NFC_SPI_MISO_PORT GPIOB
+#define NFC_SPI_MISO_PIN GPIO_PIN_4
+#define NFC_SPI_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
+#define NFC_SPI_MOSI_PORT GPIOB
+#define NFC_SPI_MOSI_PIN GPIO_PIN_5
+#define NFC_SPI_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
+#define NFC_SPI_SCK_PORT GPIOG
+#define NFC_SPI_SCK_PIN GPIO_PIN_9
+#define NFC_SPI_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
+#define NFC_SPI_NSS_PORT GPIOG
+#define NFC_SPI_NSS_PIN GPIO_PIN_12
+#define NFC_SPI_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_INT_PIN GPIO_PIN_10
#define NFC_INT_PORT GPIOG
diff --git a/core/embed/models/T3W1/boards/trezor_t3w1_revB.h b/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
index 63f522633d..d2f0af4138 100644
--- a/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
+++ b/core/embed/models/T3W1/boards/trezor_t3w1_revB.h
@@ -166,22 +166,24 @@
#define NRF_OUT_FW_RUNNING_PORT GPIOE
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
-#define SPI_INSTANCE_3 SPI3
-#define SPI_INSTANCE_3_PIN_AF GPIO_AF6_SPI3
-#define SPI_INSTANCE_3_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
-#define SPI_INSTANCE_3_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
-#define SPI_INSTANCE_3_MISO_PORT GPIOB
-#define SPI_INSTANCE_3_MISO_PIN GPIO_PIN_4
-#define SPI_INSTANCE_3_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
-#define SPI_INSTANCE_3_MOSI_PORT GPIOB
-#define SPI_INSTANCE_3_MOSI_PIN GPIO_PIN_5
-#define SPI_INSTANCE_3_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
-#define SPI_INSTANCE_3_SCK_PORT GPIOG
-#define SPI_INSTANCE_3_SCK_PIN GPIO_PIN_9
-#define SPI_INSTANCE_3_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
-#define SPI_INSTANCE_3_NSS_PORT GPIOG
-#define SPI_INSTANCE_3_NSS_PIN GPIO_PIN_12
-#define SPI_INSTANCE_3_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
+#define NFC_SPI_INSTANCE SPI3
+#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
+#define NFC_SPI_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
+#define NFC_SPI_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
+#define NFC_SPI_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET
+#define NFC_SPI_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET
+#define NFC_SPI_MISO_PORT GPIOB
+#define NFC_SPI_MISO_PIN GPIO_PIN_4
+#define NFC_SPI_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
+#define NFC_SPI_MOSI_PORT GPIOB
+#define NFC_SPI_MOSI_PIN GPIO_PIN_5
+#define NFC_SPI_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
+#define NFC_SPI_SCK_PORT GPIOG
+#define NFC_SPI_SCK_PIN GPIO_PIN_9
+#define NFC_SPI_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
+#define NFC_SPI_NSS_PORT GPIOG
+#define NFC_SPI_NSS_PIN GPIO_PIN_12
+#define NFC_SPI_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_INT_PIN GPIO_PIN_10
#define NFC_INT_PORT GPIOG
diff --git a/core/embed/projects/prodtest/README.md b/core/embed/projects/prodtest/README.md
index c3ee5202d6..e5f6c0b468 100644
--- a/core/embed/projects/prodtest/README.md
+++ b/core/embed/projects/prodtest/README.md
@@ -545,3 +545,48 @@ Example:
optiga-counter-read
OK 0E
```
+
+
+### nfc-read-card
+Activate the NFC in reader mode for a given time. Read general information from firstly discovered NFC tag or exits on timeout.
+
+Example:
+```
+nfc-read-card
+# NFC activated in reader mode for seconds.
+# NFC card detected.
+# NFC Type A: UID: %s
+OK
+```
+
+
+### nfc-emulate-card
+Activate NFC in Card Emulator mode for given time.
+
+Example:
+```
+nfc-emulate-card
+# Emulation started for
+# Emulation over
+OK
+```
+
+### nfc-write-card
+Activates the NFC reader for given time. Writes the NDEF URI message into the first discovered NFC tag type A or exits on timeout.
+
+Example:
+```
+nfc-write_card
+# NFC reader on, put the card on the reader (timeout s)
+# Writting URI to NFC tag 7AF403
+OK
+```
+
+
+
+
+
+
+
+
+
diff --git a/core/embed/projects/prodtest/cmd/prodtest_nfc.c b/core/embed/projects/prodtest/cmd/prodtest_nfc.c
index 05201d5dd8..56176fdfba 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_nfc.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_nfc.c
@@ -25,21 +25,8 @@
#include
#include
-static bool nfc_dev_activated = false;
static nfc_dev_info_t dev_info = {0};
-static void nfc_activated_callback() {
- nfc_dev_read_info(&dev_info);
- nfc_dev_activated = true;
-}
-
-static void nfc_write_tag_callback() {
- nfc_dev_info_t dev_info;
- nfc_dev_read_info(&dev_info);
-
- nfc_dev_activated = true;
-}
-
static void prodtest_nfc_read_card(cli_t* cli) {
uint32_t timeout = 0;
memset(&dev_info, 0, sizeof(dev_info));
@@ -55,31 +42,41 @@ static void prodtest_nfc_read_card(cli_t* cli) {
return;
}
- nfc_dev_activated = false;
-
nfc_status_t ret = nfc_init();
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
- cli_trace(cli, "NFC activated in reader mode for %d seconds.", timeout);
+ cli_trace(cli, "NFC activated in reader mode for %d ms.", timeout);
}
nfc_register_tech(NFC_POLLER_TECH_A | NFC_POLLER_TECH_B | NFC_POLLER_TECH_F |
NFC_POLLER_TECH_V);
- nfc_register_event_callback(NFC_STATE_ACTIVATED, nfc_activated_callback);
nfc_activate_stm();
- uint32_t tick = systick_ms();
+ nfc_event_t nfc_event = NFC_NO_EVENT;
- while (!nfc_dev_activated) { // Todo, while timeout or device found
+ uint32_t expire_time = ticks_timeout(timeout);
- if ((systick_ms() - tick) > (timeout * 1000)) {
+ while (true) {
+
+ if (ticks_expired(expire_time)) {
nfc_deinit();
cli_error(cli, CLI_ERROR_TIMEOUT, "NFC timeout");
return;
}
- nfc_feed_worker();
+ nfc_event = nfc_get_event();
+
+ if(nfc_event == NFC_STATE_ACTIVATED) {
+ nfc_dev_read_info(&dev_info);
+ nfc_dev_deactivate();
+ break;
+ }
+
+ if (cli_aborted(cli)) {
+ return;
+ }
+
}
cli_trace(cli, "NFC card detected.");
@@ -136,16 +133,21 @@ static void prodtest_nfc_emulate_card(cli_t* cli) {
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
- cli_trace(cli, "Emulation started for %d seconds", timeout);
+ cli_trace(cli, "Emulation started for %d ms", timeout);
}
nfc_register_tech(NFC_CARD_EMU_TECH_A);
nfc_activate_stm();
- uint32_t tick = systick_ms();
+ uint32_t expire_time = ticks_timeout(timeout);
+
+ while (!ticks_expired(expire_time)) {
+ nfc_get_event();
+
+ if (cli_aborted(cli)) {
+ return;
+ }
- while ((systick_ms() - tick) < (timeout * 1000)) {
- nfc_feed_worker();
}
cli_trace(cli, "Emulation over");
@@ -170,41 +172,52 @@ static void prodtest_nfc_write_card(cli_t* cli) {
return;
}
- nfc_dev_activated = false;
-
nfc_status_t ret = nfc_init();
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
- cli_trace(cli, "NFC reader on put the card on the reader (timeout %d s)",
+ cli_trace(cli, "NFC reader on, put the card on the reader (timeout %d ms)",
timeout);
}
nfc_register_tech(NFC_POLLER_TECH_A);
- nfc_register_event_callback(NFC_STATE_ACTIVATED, nfc_write_tag_callback);
nfc_activate_stm();
- uint32_t tick = systick_ms();
+ nfc_event_t nfc_event = NFC_NO_EVENT;
+ uint32_t expire_time = ticks_timeout(timeout);
- while (!nfc_dev_activated) { // Todo, while timeout or device found
+ while (true) {
- if ((systick_ms() - tick) > timeout * 1000) {
+ if (ticks_expired(expire_time)) {
nfc_deinit();
cli_error(cli, CLI_ERROR_TIMEOUT, "NFC timeout");
return;
}
- nfc_feed_worker();
- }
+ nfc_event = nfc_get_event();
+ if (nfc_event == NFC_STATE_ACTIVATED) {
- if (dev_info.type != NFC_DEV_TYPE_A) {
- cli_error(cli, CLI_ERROR, "Only NFC type A cards supported");
- return;
- }
+ nfc_dev_read_info(&dev_info);
- cli_trace(cli, "Writting URI to NFC tag %s", dev_info.uid);
- nfc_def_write_ndef_uri();
+ if (dev_info.type != NFC_DEV_TYPE_A) {
+ cli_error(cli, CLI_ERROR, "Only NFC type A cards supported");
+ return;
+ }
+
+ cli_trace(cli, "Writting URI to NFC tag %s", dev_info.uid);
+ nfc_dev_write_ndef_uri();
+
+ nfc_dev_deactivate();
+ break;
+
+ }
+
+ if (cli_aborted(cli)) {
+ return;
+ }
+
+ }
nfc_deinit();