-
-
Notifications
You must be signed in to change notification settings - Fork 721
Introduce driver for ST25TV tag #6167
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
base: main
Are you sure you want to change the base?
Conversation
[no chagelog]
[no changelog]
[no changelog]
[no changelog]
|
Looks like you changed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a new dedicated driver for ST25TV NFC tags, operating in parallel with the existing general NFC driver. The implementation provides core operations (initialization, connection management, read/write, wipe) via a new syscall interface, integrates an event-based polling mechanism into the system event loop, and extends prodtest with comprehensive testing commands.
Key changes:
- New NFC backup driver with dedicated API (
nfc_backup.h) and syscall interface - Refactored SPI handling to share hardware between NFC and NFC backup drivers
- Event-driven architecture using system event polling rather than manual worker polling
- Comprehensive prodtest commands for testing all driver operations
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
core/site_scons/models/T3W1/trezor_t3w1_revC.py |
Adds new source files for NFC backup driver to build configuration |
core/embed/sys/task/inc/sys/sysevent.h |
Adds SYSHANDLE_NFC_BACKUP event handle for event loop integration |
core/embed/sys/syscall/stm32/syscall_verifiers.h |
Declares syscall verifier functions for NFC backup operations |
core/embed/sys/syscall/stm32/syscall_verifiers.c |
Implements memory access validation for NFC backup syscalls |
core/embed/sys/syscall/stm32/syscall_stubs.c |
Implements userspace syscall stubs for NFC backup API |
core/embed/sys/syscall/stm32/syscall_dispatch.c |
Routes NFC backup syscalls to kernel implementations |
core/embed/sys/syscall/inc/sys/syscall_numbers.h |
Defines syscall numbers for NFC backup operations |
core/embed/rust/src/ui/ui_prodtest.rs |
Adds UI trait method for NFC tag connection visualization |
core/embed/rust/src/ui/layout_eckhart/prodtest/mod.rs |
Implements NFC tag connection screen with visual feedback |
core/embed/rust/src/ui/api/prodtest_c.rs |
Exposes Rust UI function to C code |
core/embed/rust/rust_ui_prodtest.h |
Declares C interface for NFC prodtest UI |
core/embed/projects/prodtest/main.c |
Includes NFC backup header for prodtest usage |
core/embed/projects/prodtest/cmd/prodtest_nfc.c |
Implements 8 prodtest commands for NFC backup testing |
core/embed/projects/prodtest/README.md |
Documents all new prodtest commands with examples |
core/embed/io/nfc/st25r3916b/rfal_platform.h |
Removes circular include dependency |
core/embed/io/nfc/st25r3916b/nfc_spi.c |
Extracts SPI handling into shared module |
core/embed/io/nfc/st25r3916b/nfc_internal.h |
Declares shared SPI functions for both drivers |
core/embed/io/nfc/st25r3916b/nfc_backup_poll.h |
Declares event polling functions for NFC backup |
core/embed/io/nfc/st25r3916b/nfc_backup_poll.c |
Implements event-based polling for NFC backup |
core/embed/io/nfc/st25r3916b/nfc_backup.c |
Core NFC backup driver implementation |
core/embed/io/nfc/st25r3916b/nfc.c |
Refactored to use shared SPI module |
core/embed/io/nfc/inc/io/nfc_backup.h |
Public API header for NFC backup driver |
Comments suppressed due to low confidence (1)
core/embed/io/nfc/st25r3916b/nfc_backup.c:1
- Corrected spelling of 'precisly' to 'precisely'.
/*
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | ||
| SYSCALL_NFC_BACKUP_READ_DATA); | ||
| } | ||
|
|
||
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | ||
| size_t data_size) { | ||
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function parameters are block_number, data, and data_size, but the syscall is invoked with undefined variables start_block and num_blocks. This should be syscall_invoke3(block_number, (uint32_t)data, data_size, ...) to match the function signature.
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | |
| SYSCALL_NFC_BACKUP_READ_DATA); | |
| } | |
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | |
| size_t data_size) { | |
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | |
| return (bool)syscall_invoke3(block_number, (uint32_t)data, data_size, | |
| SYSCALL_NFC_BACKUP_READ_DATA); | |
| } | |
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | |
| size_t data_size) { | |
| return (bool)syscall_invoke3(block_number, (uint32_t)data, data_size, |
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | ||
| SYSCALL_NFC_BACKUP_READ_DATA); | ||
| } | ||
|
|
||
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | ||
| size_t data_size) { | ||
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function parameters are block_number, data, and data_size, but the syscall is invoked with undefined variables start_block and num_blocks. This should be syscall_invoke3(block_number, (uint32_t)data, data_size, ...) to match the function signature.
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | |
| SYSCALL_NFC_BACKUP_READ_DATA); | |
| } | |
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | |
| size_t data_size) { | |
| return (bool)syscall_invoke3(start_block, (uint32_t)data, num_blocks, | |
| return (bool)syscall_invoke3(block_number, (uint32_t)data, data_size, | |
| SYSCALL_NFC_BACKUP_READ_DATA); | |
| } | |
| bool nfc_backup_write_data(uint16_t block_number, const uint8_t *data, | |
| size_t data_size) { | |
| return (bool)syscall_invoke3(block_number, (uint32_t)data, data_size, |
| ``` | ||
|
|
||
| ### nfc-backup-store-secret | ||
| Activates NFC reader and store the secret phrese on the connected tag. |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'phrese' to 'phrase'.
| ``` | ||
|
|
||
| ### nfc-backup-read-secret | ||
| Activates NFC reader and read the secret phrese from the connected tag. |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'phrese' to 'phrase'.
| } | ||
|
|
||
| uint8_t data_buffer[1] = {0}; | ||
| uint8_t recieved_buf[7] = {0}; |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'recieved' to 'received'.
| response, sizeof(response), &received_length); | ||
|
|
||
| if (received_length != 3) { | ||
| return RFAL_ERR_PROTO; |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function return type is bool but returns RFAL_ERR_PROTO (likely an enum/int). This should return false to match the function signature.
| return RFAL_ERR_PROTO; | |
| return false; |
| if (enable) { | ||
| data[2] = 0x05; // Boot to silent mode regardless of DS_STS | ||
| } else { | ||
| data[2] = 0x00; // Disbale silent mode |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'Disbale' to 'Disable'.
| data[2] = 0x00; // Disbale silent mode | |
| data[2] = 0x00; // Disable silent mode |
| system_info->mem_block_count = response[12] + 1; // Block size in bytes | ||
| system_info->mem_block_size = response[13] + 1; // Number of blocks |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments appear to be swapped. Line 374 assigns to mem_block_count but the comment says 'Block size in bytes', while line 375 assigns to mem_block_size but the comment says 'Number of blocks'. The comments should be swapped to match the variables.
| system_info->mem_block_count = response[12] + 1; // Block size in bytes | |
| system_info->mem_block_size = response[13] + 1; // Number of blocks | |
| system_info->mem_block_count = response[12] + 1; // Number of blocks | |
| system_info->mem_block_size = response[13] + 1; // Block size in bytes |
| .func = prodtest_nfc_backup_store_secret, | ||
| .info = "Store secret data to NFC backup tag", | ||
| .args = "<secret>" | ||
| ); |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace after closing parenthesis should be removed.
| ); | |
| ); |
| .func = prodtest_nfc_backup_wipe_memory, | ||
| .info = "Wipe NFC backup memory", | ||
| .args = "" | ||
| ) |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon after closing parenthesis. Should be ); to match the pattern used in other command definitions.
| ) | |
| ); |
|
| model | device_test | click_test | persistence_test |
|---|---|---|---|
| T2T1 | test(all) main(all) ![]() |
test(all) main(all) ![]() |
test(all) main(all) ![]() |
| T3B1 | test(all) main(all) ![]() |
test(all) main(all) ![]() |
test(all) main(all) ![]() |
| T3T1 | test(all) main(all) ![]() |
test(all) main(all) ![]() |
test(all) main(all) ![]() |
| T3W1 | test(all) main(all) ![]() |
test(all) main(all) ![]() |
test(all) main(all) ![]() |
Latest CI run: 19503676208




































This PR brings support for ST25TV tag.
Implementation details
New driver exclusive for ST25TV tag was implemented in parallel to current NFC driver. Old NFC driver provides general support for many kinds technologies and implementing a driver for ST25TV (as a proprietary technology) would add another layer on the top of the already many layer driver. NFC driver would then work only as a trampoline, which did not make sense.
Both drivers are attached to same SPI peripheral, so user can select which driver to use, but should not use both simultaneously.
Driver provide functions to initiate a connections with the tag, read out basic system information, read and write to the tag memory, wipe the memory, but do not provide any complex memory handling operations which will be implemented in the upper level.
Event loop
Compared to general NFC driver, ST25TV driver do not require to poll for RfalWorker function when running NFC discover. Instead, RfalWorker was embedded to event loop poll and user could react to incoming events.
Prodtest
Implementation was extended with several prodtest commands allowing to test basic driver operations.