ESPHome 2026.5.1
Loading...
Searching...
No Matches
pn7150.h
Go to the documentation of this file.
1#pragma once
2
9#include "esphome/core/gpio.h"
11
12#include <functional>
13
14namespace esphome::pn7150 {
15
16static constexpr uint16_t NFCC_DEFAULT_TIMEOUT = 10;
17static constexpr uint16_t NFCC_INIT_TIMEOUT = 50;
18static constexpr uint16_t NFCC_TAG_WRITE_TIMEOUT = 15;
19
20static constexpr uint8_t NFCC_MAX_COMM_FAILS = 3;
21static constexpr uint8_t NFCC_MAX_ERROR_COUNT = 10;
22
23static constexpr uint8_t XCHG_DATA_OID = 0x10;
24static constexpr uint8_t MF_SECTORSEL_OID = 0x32;
25static constexpr uint8_t MFC_AUTHENTICATE_OID = 0x40;
26static constexpr uint8_t TEST_PRBS_OID = 0x30;
27static constexpr uint8_t TEST_ANTENNA_OID = 0x3D;
28static constexpr uint8_t TEST_GET_REGISTER_OID = 0x33;
29
30static constexpr uint8_t MFC_AUTHENTICATE_PARAM_KS_A = 0x00; // key select A
31static constexpr uint8_t MFC_AUTHENTICATE_PARAM_KS_B = 0x80; // key select B
32static constexpr uint8_t MFC_AUTHENTICATE_PARAM_EMBED_KEY = 0x10;
33
34static constexpr uint8_t CARD_EMU_T4T_APP_SELECT[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76,
35 0x00, 0x00, 0x85, 0x01, 0x01, 0x00};
36static constexpr uint8_t CARD_EMU_T4T_CC[] = {0x00, 0x0F, 0x20, 0x00, 0xFF, 0x00, 0xFF, 0x04,
37 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00};
38static constexpr uint8_t CARD_EMU_T4T_CC_SELECT[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x03};
39static constexpr uint8_t CARD_EMU_T4T_NDEF_SELECT[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x04};
40static constexpr uint8_t CARD_EMU_T4T_READ[] = {0x00, 0xB0};
41static constexpr uint8_t CARD_EMU_T4T_WRITE[] = {0x00, 0xD6};
42static constexpr uint8_t CARD_EMU_T4T_OK[] = {0x90, 0x00};
43static constexpr uint8_t CARD_EMU_T4T_NOK[] = {0x6A, 0x82};
44
45static constexpr uint8_t CORE_CONFIG_SOLO[] = {0x01, // Number of parameter fields
46 0x00, // config param identifier (TOTAL_DURATION)
47 0x02, // length of value
48 0x01, // TOTAL_DURATION (low)...
49 0x00}; // TOTAL_DURATION (high): 1 ms
50
51static constexpr uint8_t CORE_CONFIG_RW_CE[] = {0x01, // Number of parameter fields
52 0x00, // config param identifier (TOTAL_DURATION)
53 0x02, // length of value
54 0xF8, // TOTAL_DURATION (low)...
55 0x02}; // TOTAL_DURATION (high): 760 ms
56
57static constexpr uint8_t PMU_CFG[] = {
58 0x01, // Number of parameters
59 0xA0, 0x0E, // ext. tag
60 3, // length
61 0x06, // VBAT1 connected to 5V (CFG2)
62 0x64, // TVDD monitoring threshold = 5.0V; TxLDO voltage = 4.7V (in reader & card modes)
63 0x01, // RFU; must be 0x00 for CFG1 and 0x01 for CFG2
64};
65
66static constexpr uint8_t RF_DISCOVER_MAP_CONFIG[] = { // poll modes
67 nfc::PROT_T1T, nfc::RF_DISCOVER_MAP_MODE_POLL,
68 nfc::INTF_FRAME, // poll mode
69 nfc::PROT_T2T, nfc::RF_DISCOVER_MAP_MODE_POLL,
70 nfc::INTF_FRAME, // poll mode
71 nfc::PROT_T3T, nfc::RF_DISCOVER_MAP_MODE_POLL,
72 nfc::INTF_FRAME, // poll mode
73 nfc::PROT_ISODEP, nfc::RF_DISCOVER_MAP_MODE_POLL | nfc::RF_DISCOVER_MAP_MODE_LISTEN,
74 nfc::INTF_ISODEP, // poll & listen mode
75 nfc::PROT_MIFARE, nfc::RF_DISCOVER_MAP_MODE_POLL,
76 nfc::INTF_TAGCMD}; // poll mode
77
78static constexpr uint8_t RF_DISCOVERY_LISTEN_CONFIG[] = {
79 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCA, // listen mode
80 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCB, // listen mode
81 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCF}; // listen mode
82
83static constexpr uint8_t RF_DISCOVERY_POLL_CONFIG[] = {nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCA, // poll mode
84 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCB, // poll mode
85 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCF}; // poll mode
86
87static constexpr uint8_t RF_DISCOVERY_CONFIG[] = {nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCA, // poll mode
88 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCB, // poll mode
89 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCF, // poll mode
90 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCA, // listen mode
91 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCB, // listen mode
92 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCF}; // listen mode
93
94static constexpr uint8_t RF_LISTEN_MODE_ROUTING_CONFIG[] = {0x00, // "more" (another message is coming)
95 1, // number of table entries
96 0x01, // type = protocol-based
97 3, // length
98 0, // DH NFCEE ID, a static ID representing the DH-NFCEE
99 0x01, // power state
100 nfc::PROT_ISODEP}; // protocol
101
109
129
130enum class TestMode : uint8_t {
131 TEST_NONE = 0x00,
132 TEST_PRBS,
135};
136
138 uint8_t id;
139 uint8_t protocol;
141 std::unique_ptr<nfc::NfcTag> tag;
143};
144
145class PN7150 : public nfc::Nfcc, public Component {
146 public:
147 void setup() override;
148 void dump_config() override;
149 void loop() override;
150
151 void set_irq_pin(GPIOPin *irq_pin) { this->irq_pin_ = irq_pin; }
152 void set_ven_pin(GPIOPin *ven_pin) { this->ven_pin_ = ven_pin; }
153
155 void set_tag_emulation_message(std::shared_ptr<nfc::NdefMessage> message);
156 void set_tag_emulation_message(const optional<std::string> &message, optional<bool> include_android_app_record);
157 void set_tag_emulation_message(const char *message, bool include_android_app_record = true);
161
162 void set_polling_off();
163 void set_polling_on();
164 bool polling_enabled() { return this->polling_enabled_; }
165
166 void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
168
169 template<typename F> void add_on_emulated_tag_scan_callback(F &&callback) {
170 this->on_emulated_tag_scan_callback_.add(std::forward<F>(callback));
171 }
172
173 template<typename F> void add_on_finished_write_callback(F &&callback) {
174 this->on_finished_write_callback_.add(std::forward<F>(callback));
175 }
176
177 bool is_writing() { return this->next_task_ != EP_READ; };
178
179 void read_mode();
180 void clean_mode();
181 void format_mode();
182 void write_mode();
183 void set_tag_write_message(std::shared_ptr<nfc::NdefMessage> message);
184 void set_tag_write_message(optional<std::string> message, optional<bool> include_android_app_record);
185
186 uint8_t set_test_mode(TestMode test_mode, const std::vector<uint8_t> &data, std::vector<uint8_t> &result);
187
188 protected:
189 uint8_t reset_core_(bool reset_config, bool power);
190 uint8_t init_core_();
191 uint8_t send_init_config_();
192 uint8_t send_core_config_();
193 uint8_t refresh_core_config_();
194
195 uint8_t set_discover_map_();
196
197 uint8_t set_listen_mode_routing_();
198
199 uint8_t start_discovery_();
200 uint8_t stop_discovery_();
201 uint8_t deactivate_(uint8_t type, uint16_t timeout = NFCC_DEFAULT_TIMEOUT);
202
203 void select_endpoint_();
204
206 uint8_t clean_endpoint_(nfc::NfcTagUid &uid);
207 uint8_t format_endpoint_(nfc::NfcTagUid &uid);
208 uint8_t write_endpoint_(nfc::NfcTagUid &uid, std::shared_ptr<nfc::NdefMessage> &message);
209
210 std::unique_ptr<nfc::NfcTag> build_tag_(uint8_t mode_tech, const std::vector<uint8_t> &data);
211 optional<size_t> find_tag_uid_(const nfc::NfcTagUid &uid);
212 void purge_old_tags_();
213 void erase_tag_(uint8_t tag_index);
214
216 void nci_fsm_transition_();
218 void nci_fsm_set_state_(NCIState new_state);
220 bool nci_fsm_set_error_state_(NCIState new_state);
222 void process_message_();
227
228 void card_emu_t4t_get_response_(std::vector<uint8_t> &response, std::vector<uint8_t> &ndef_response);
229
230 uint8_t transceive_(nfc::NciMessage &tx, nfc::NciMessage &rx, uint16_t timeout = NFCC_DEFAULT_TIMEOUT,
231 bool expect_notification = true);
232 virtual uint8_t read_nfcc(nfc::NciMessage &rx, uint16_t timeout) = 0;
233 virtual uint8_t write_nfcc(nfc::NciMessage &tx) = 0;
234
235 uint8_t wait_for_irq_(uint16_t timeout = NFCC_DEFAULT_TIMEOUT, bool pin_state = true);
236
238 uint8_t read_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
239 uint8_t write_mifare_classic_block_(uint8_t block_num, const uint8_t *data, size_t len);
240 uint8_t auth_mifare_classic_block_(uint8_t block_num, uint8_t key_num, const uint8_t *key);
241 uint8_t sect_to_auth_(uint8_t block_num);
244 uint8_t write_mifare_classic_tag_(const std::shared_ptr<nfc::NdefMessage> &message);
245 uint8_t halt_mifare_classic_tag_();
246
248 uint8_t read_mifare_ultralight_bytes_(uint8_t start_page, uint16_t num_bytes, std::vector<uint8_t> &data);
249 bool is_mifare_ultralight_formatted_(const std::vector<uint8_t> &page_3_to_6);
251 uint8_t find_mifare_ultralight_ndef_(const std::vector<uint8_t> &page_3_to_6, uint8_t &message_length,
252 uint8_t &message_start_index);
253 uint8_t write_mifare_ultralight_page_(uint8_t page_num, const uint8_t *write_data, size_t len);
254 uint8_t write_mifare_ultralight_tag_(nfc::NfcTagUid &uid, const std::shared_ptr<nfc::NdefMessage> &message);
255 uint8_t clean_mifare_ultralight_();
256
257 enum NfcTask : uint8_t {
262 } next_task_{EP_READ};
263
268
269 uint8_t error_count_{0};
270 uint8_t fail_count_{0};
274
275 GPIOPin *irq_pin_{nullptr};
276 GPIOPin *ven_pin_{nullptr};
277
280
281 std::vector<DiscoveredEndpoint> discovered_endpoint_;
282
286
287 std::shared_ptr<nfc::NdefMessage> card_emulation_message_;
288 std::shared_ptr<nfc::NdefMessage> next_task_message_to_write_;
289
290 std::vector<nfc::NfcOnTagTrigger *> triggers_ontag_;
291 std::vector<nfc::NfcOnTagTrigger *> triggers_ontagremoved_;
292};
293
294} // namespace esphome::pn7150
void process_message_()
parse & process incoming messages from the NFCC
Definition pn7150.cpp:713
uint8_t wait_for_irq_(uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool pin_state=true)
Definition pn7150.cpp:1150
std::vector< nfc::NfcOnTagTrigger * > triggers_ontagremoved_
Definition pn7150.h:291
uint8_t format_endpoint_(nfc::NfcTagUid &uid)
Definition pn7150.cpp:495
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig)
Definition pn7150.h:167
std::shared_ptr< nfc::NdefMessage > next_task_message_to_write_
Definition pn7150.h:288
uint8_t write_mifare_classic_tag_(const std::shared_ptr< nfc::NdefMessage > &message)
uint8_t transceive_(nfc::NciMessage &tx, nfc::NciMessage &rx, uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool expect_notification=true)
Definition pn7150.cpp:1093
std::unique_ptr< nfc::NfcTag > build_tag_(uint8_t mode_tech, const std::vector< uint8_t > &data)
Definition pn7150.cpp:527
void nci_fsm_transition_()
advance controller state as required
Definition pn7150.cpp:585
uint8_t read_mifare_ultralight_tag_(nfc::NfcTag &tag)
uint8_t read_mifare_ultralight_bytes_(uint8_t start_page, uint16_t num_bytes, std::vector< uint8_t > &data)
CardEmulationState ce_state_
Definition pn7150.h:283
uint8_t find_mifare_ultralight_ndef_(const std::vector< uint8_t > &page_3_to_6, uint8_t &message_length, uint8_t &message_start_index)
void set_irq_pin(GPIOPin *irq_pin)
Definition pn7150.h:151
std::vector< DiscoveredEndpoint > discovered_endpoint_
Definition pn7150.h:281
void process_rf_intf_activated_oid_(nfc::NciMessage &rx)
Definition pn7150.cpp:808
void card_emu_t4t_get_response_(std::vector< uint8_t > &response, std::vector< uint8_t > &ndef_response)
Definition pn7150.cpp:999
void loop() override
Definition pn7150.cpp:27
uint8_t deactivate_(uint8_t type, uint16_t timeout=NFCC_DEFAULT_TIMEOUT)
Definition pn7150.cpp:419
void process_data_message_(nfc::NciMessage &rx)
Definition pn7150.cpp:977
void set_ven_pin(GPIOPin *ven_pin)
Definition pn7150.h:152
virtual uint8_t read_nfcc(nfc::NciMessage &rx, uint16_t timeout)=0
optional< size_t > find_tag_uid_(const nfc::NfcTagUid &uid)
Definition pn7150.cpp:544
bool nci_fsm_set_error_state_(NCIState new_state)
setting controller to this state caused an error; returns true if too many errors/failures
Definition pn7150.cpp:696
void set_tag_ttl(uint32_t ttl)
Definition pn7150.h:154
uint8_t write_endpoint_(nfc::NfcTagUid &uid, std::shared_ptr< nfc::NdefMessage > &message)
Definition pn7150.cpp:511
void set_tag_emulation_message(std::shared_ptr< nfc::NdefMessage > message)
Definition pn7150.cpp:32
void set_tag_write_message(std::shared_ptr< nfc::NdefMessage > message)
Definition pn7150.cpp:124
uint8_t read_mifare_classic_block_(uint8_t block_num, std::vector< uint8_t > &data)
uint8_t set_listen_mode_routing_()
Definition pn7150.cpp:363
NCIState nci_state_error_
Definition pn7150.h:285
uint8_t write_mifare_ultralight_page_(uint8_t page_num, const uint8_t *write_data, size_t len)
void process_rf_deactivate_oid_(nfc::NciMessage &rx)
Definition pn7150.cpp:949
uint8_t refresh_core_config_()
Definition pn7150.cpp:328
bool is_mifare_ultralight_formatted_(const std::vector< uint8_t > &page_3_to_6)
uint8_t selecting_endpoint_
Definition pn7150.h:272
bool tag_emulation_enabled()
Definition pn7150.h:160
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig)
Definition pn7150.h:166
uint8_t send_init_config_()
Definition pn7150.cpp:285
void erase_tag_(uint8_t tag_index)
Definition pn7150.cpp:571
uint8_t set_test_mode(TestMode test_mode, const std::vector< uint8_t > &data, std::vector< uint8_t > &result)
Definition pn7150.cpp:150
uint8_t clean_endpoint_(nfc::NfcTagUid &uid)
Definition pn7150.cpp:479
CallbackManager< void()> on_finished_write_callback_
Definition pn7150.h:279
uint8_t read_mifare_classic_tag_(nfc::NfcTag &tag)
uint8_t reset_core_(bool reset_config, bool power)
Definition pn7150.cpp:212
void setup() override
Definition pn7150.cpp:14
uint8_t send_core_config_()
Definition pn7150.cpp:305
void nci_fsm_set_state_(NCIState new_state)
set new controller state
Definition pn7150.cpp:688
uint8_t stop_discovery_()
Definition pn7150.cpp:417
uint8_t write_mifare_classic_block_(uint8_t block_num, const uint8_t *data, size_t len)
uint8_t read_endpoint_data_(nfc::NfcTag &tag)
Definition pn7150.cpp:459
std::vector< nfc::NfcOnTagTrigger * > triggers_ontag_
Definition pn7150.h:290
void dump_config() override
Definition pn7150.cpp:21
uint8_t auth_mifare_classic_block_(uint8_t block_num, uint8_t key_num, const uint8_t *key)
uint8_t set_discover_map_()
Definition pn7150.cpp:349
void add_on_finished_write_callback(F &&callback)
Definition pn7150.h:173
CallbackManager< void()> on_emulated_tag_scan_callback_
Definition pn7150.h:278
uint8_t write_mifare_ultralight_tag_(nfc::NfcTagUid &uid, const std::shared_ptr< nfc::NdefMessage > &message)
uint32_t last_nci_state_change_
Definition pn7150.h:271
uint8_t start_discovery_()
Definition pn7150.cpp:376
void add_on_emulated_tag_scan_callback(F &&callback)
Definition pn7150.h:169
void process_rf_discover_oid_(nfc::NciMessage &rx)
Definition pn7150.cpp:922
std::shared_ptr< nfc::NdefMessage > card_emulation_message_
Definition pn7150.h:287
uint8_t sect_to_auth_(uint8_t block_num)
enum esphome::pn7150::PN7150::NfcTask EP_READ
virtual uint8_t write_nfcc(nfc::NciMessage &tx)=0
const char * message
Definition component.cpp:35
uint16_t type
uint32_t ttl
const char * tag
Definition log.h:74
std::string size_t len
static void uint32_t
std::unique_ptr< nfc::NfcTag > tag
Definition pn7150.h:141