ESPHome 2025.5.0
Loading...
Searching...
No Matches
pn7160.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 {
15namespace pn7160 {
16
17static const uint16_t NFCC_DEFAULT_TIMEOUT = 10;
18static const uint16_t NFCC_INIT_TIMEOUT = 50;
19static const uint16_t NFCC_TAG_WRITE_TIMEOUT = 15;
20
21static const uint8_t NFCC_MAX_COMM_FAILS = 3;
22static const uint8_t NFCC_MAX_ERROR_COUNT = 10;
23
24static const uint8_t XCHG_DATA_OID = 0x10;
25static const uint8_t MF_SECTORSEL_OID = 0x32;
26static const uint8_t MFC_AUTHENTICATE_OID = 0x40;
27static const uint8_t TEST_PRBS_OID = 0x30;
28static const uint8_t TEST_ANTENNA_OID = 0x3D;
29static const uint8_t TEST_GET_REGISTER_OID = 0x33;
30
31static const uint8_t MFC_AUTHENTICATE_PARAM_KS_A = 0x00; // key select A
32static const uint8_t MFC_AUTHENTICATE_PARAM_KS_B = 0x80; // key select B
33static const uint8_t MFC_AUTHENTICATE_PARAM_EMBED_KEY = 0x10;
34
35static const uint8_t CARD_EMU_T4T_APP_SELECT[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76,
36 0x00, 0x00, 0x85, 0x01, 0x01, 0x00};
37static const uint8_t CARD_EMU_T4T_CC[] = {0x00, 0x0F, 0x20, 0x00, 0xFF, 0x00, 0xFF, 0x04,
38 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00};
39static const uint8_t CARD_EMU_T4T_CC_SELECT[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x03};
40static const uint8_t CARD_EMU_T4T_NDEF_SELECT[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x04};
41static const uint8_t CARD_EMU_T4T_READ[] = {0x00, 0xB0};
42static const uint8_t CARD_EMU_T4T_WRITE[] = {0x00, 0xD6};
43static const uint8_t CARD_EMU_T4T_OK[] = {0x90, 0x00};
44static const uint8_t CARD_EMU_T4T_NOK[] = {0x6A, 0x82};
45
46static const uint8_t CORE_CONFIG_SOLO[] = {0x01, // Number of parameter fields
47 0x00, // config param identifier (TOTAL_DURATION)
48 0x02, // length of value
49 0x01, // TOTAL_DURATION (low)...
50 0x00}; // TOTAL_DURATION (high): 1 ms
51
52static const uint8_t CORE_CONFIG_RW_CE[] = {0x01, // Number of parameter fields
53 0x00, // config param identifier (TOTAL_DURATION)
54 0x02, // length of value
55 0xF8, // TOTAL_DURATION (low)...
56 0x02}; // TOTAL_DURATION (high): 760 ms
57
58static const uint8_t PMU_CFG[] = {
59 0x01, // Number of parameters
60 0xA0, 0x0E, // ext. tag
61 11, // length
62 0x11, // IRQ Enable: PVDD + temp sensor IRQs
63 0x01, // RFU
64 0x01, // Power and Clock Configuration, device on (CFG1)
65 0x01, // Power and Clock Configuration, device off (CFG1)
66 0x00, // RFU
67 0x00, // DC-DC 0
68 0x00, // DC-DC 1
69 // 0x14, // TXLDO (3.3V / 4.75V)
70 // 0xBB, // TXLDO (4.7V / 4.7V)
71 0xFF, // TXLDO (5.0V / 5.0V)
72 0x00, // RFU
73 0xD0, // TXLDO check
74 0x0C, // RFU
75};
76
77static const uint8_t RF_DISCOVER_MAP_CONFIG[] = { // poll modes
78 nfc::PROT_T1T, nfc::RF_DISCOVER_MAP_MODE_POLL,
79 nfc::INTF_FRAME, // poll mode
80 nfc::PROT_T2T, nfc::RF_DISCOVER_MAP_MODE_POLL,
81 nfc::INTF_FRAME, // poll mode
82 nfc::PROT_T3T, nfc::RF_DISCOVER_MAP_MODE_POLL,
83 nfc::INTF_FRAME, // poll mode
84 nfc::PROT_ISODEP, nfc::RF_DISCOVER_MAP_MODE_POLL | nfc::RF_DISCOVER_MAP_MODE_LISTEN,
85 nfc::INTF_ISODEP, // poll & listen mode
86 nfc::PROT_MIFARE, nfc::RF_DISCOVER_MAP_MODE_POLL,
87 nfc::INTF_TAGCMD}; // poll mode
88
89static const uint8_t RF_DISCOVERY_LISTEN_CONFIG[] = {nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCA, // listen mode
90 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCB, // listen mode
91 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCF}; // listen mode
92
93static const uint8_t RF_DISCOVERY_POLL_CONFIG[] = {nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCA, // poll mode
94 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCB, // poll mode
95 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCF}; // poll mode
96
97static const uint8_t RF_DISCOVERY_CONFIG[] = {nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCA, // poll mode
98 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCB, // poll mode
99 nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCF, // poll mode
100 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCA, // listen mode
101 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCB, // listen mode
102 nfc::MODE_LISTEN_MASK | nfc::TECH_PASSIVE_NFCF}; // listen mode
103
104static const uint8_t RF_LISTEN_MODE_ROUTING_CONFIG[] = {0x00, // "more" (another message is coming)
105 2, // number of table entries
106 0x01, // type = protocol-based
107 3, // length
108 0, // DH NFCEE ID, a static ID representing the DH-NFCEE
109 0x07, // power state
110 nfc::PROT_ISODEP, // protocol
111 0x00, // type = technology-based
112 3, // length
113 0, // DH NFCEE ID, a static ID representing the DH-NFCEE
114 0x07, // power state
115 nfc::TECH_PASSIVE_NFCA}; // technology
116
124
144
145enum class TestMode : uint8_t {
146 TEST_NONE = 0x00,
147 TEST_PRBS,
150};
151
153 uint8_t id;
154 uint8_t protocol;
155 uint32_t last_seen;
156 std::unique_ptr<nfc::NfcTag> tag;
158};
159
160class PN7160 : public nfc::Nfcc, public Component {
161 public:
162 void setup() override;
163 void dump_config() override;
164 float get_setup_priority() const override { return setup_priority::DATA; }
165 void loop() override;
166
167 void set_dwl_req_pin(GPIOPin *dwl_req_pin) { this->dwl_req_pin_ = dwl_req_pin; }
168 void set_irq_pin(GPIOPin *irq_pin) { this->irq_pin_ = irq_pin; }
169 void set_ven_pin(GPIOPin *ven_pin) { this->ven_pin_ = ven_pin; }
170 void set_wkup_req_pin(GPIOPin *wkup_req_pin) { this->wkup_req_pin_ = wkup_req_pin; }
171
172 void set_tag_ttl(uint32_t ttl) { this->tag_ttl_ = ttl; }
173 void set_tag_emulation_message(std::shared_ptr<nfc::NdefMessage> message);
174 void set_tag_emulation_message(const optional<std::string> &message, optional<bool> include_android_app_record);
175 void set_tag_emulation_message(const char *message, bool include_android_app_record = true);
179
180 void set_polling_off();
181 void set_polling_on();
182 bool polling_enabled() { return this->polling_enabled_; }
183
184 void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
186
187 void add_on_emulated_tag_scan_callback(std::function<void()> callback) {
188 this->on_emulated_tag_scan_callback_.add(std::move(callback));
189 }
190
191 void add_on_finished_write_callback(std::function<void()> callback) {
192 this->on_finished_write_callback_.add(std::move(callback));
193 }
194
195 bool is_writing() { return this->next_task_ != EP_READ; };
196
197 void read_mode();
198 void clean_mode();
199 void format_mode();
200 void write_mode();
201 void set_tag_write_message(std::shared_ptr<nfc::NdefMessage> message);
202 void set_tag_write_message(optional<std::string> message, optional<bool> include_android_app_record);
203
204 uint8_t set_test_mode(TestMode test_mode, const std::vector<uint8_t> &data, std::vector<uint8_t> &result);
205
206 protected:
207 uint8_t reset_core_(bool reset_config, bool power);
208 uint8_t init_core_();
209 uint8_t send_init_config_();
210 uint8_t send_core_config_();
211 uint8_t refresh_core_config_();
212
213 uint8_t set_discover_map_();
214
215 uint8_t set_listen_mode_routing_();
216
217 uint8_t start_discovery_();
218 uint8_t stop_discovery_();
219 uint8_t deactivate_(uint8_t type, uint16_t timeout = NFCC_DEFAULT_TIMEOUT);
220
221 void select_endpoint_();
222
223 uint8_t read_endpoint_data_(nfc::NfcTag &tag);
224 uint8_t clean_endpoint_(std::vector<uint8_t> &uid);
225 uint8_t format_endpoint_(std::vector<uint8_t> &uid);
226 uint8_t write_endpoint_(std::vector<uint8_t> &uid, std::shared_ptr<nfc::NdefMessage> &message);
227
228 std::unique_ptr<nfc::NfcTag> build_tag_(uint8_t mode_tech, const std::vector<uint8_t> &data);
229 optional<size_t> find_tag_uid_(const std::vector<uint8_t> &uid);
230 void purge_old_tags_();
231 void erase_tag_(uint8_t tag_index);
232
234 void nci_fsm_transition_();
236 void nci_fsm_set_state_(NCIState new_state);
238 bool nci_fsm_set_error_state_(NCIState new_state);
240 void process_message_();
245
246 void card_emu_t4t_get_response_(std::vector<uint8_t> &response, std::vector<uint8_t> &ndef_response);
247
248 uint8_t transceive_(nfc::NciMessage &tx, nfc::NciMessage &rx, uint16_t timeout = NFCC_DEFAULT_TIMEOUT,
249 bool expect_notification = true);
250 virtual uint8_t read_nfcc(nfc::NciMessage &rx, uint16_t timeout) = 0;
251 virtual uint8_t write_nfcc(nfc::NciMessage &tx) = 0;
252
253 uint8_t wait_for_irq_(uint16_t timeout = NFCC_DEFAULT_TIMEOUT, bool pin_state = true);
254
256 uint8_t read_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
257 uint8_t write_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
258 uint8_t auth_mifare_classic_block_(uint8_t block_num, uint8_t key_num, const uint8_t *key);
259 uint8_t sect_to_auth_(uint8_t block_num);
262 uint8_t write_mifare_classic_tag_(const std::shared_ptr<nfc::NdefMessage> &message);
263 uint8_t halt_mifare_classic_tag_();
264
266 uint8_t read_mifare_ultralight_bytes_(uint8_t start_page, uint16_t num_bytes, std::vector<uint8_t> &data);
267 bool is_mifare_ultralight_formatted_(const std::vector<uint8_t> &page_3_to_6);
269 uint8_t find_mifare_ultralight_ndef_(const std::vector<uint8_t> &page_3_to_6, uint8_t &message_length,
270 uint8_t &message_start_index);
271 uint8_t write_mifare_ultralight_page_(uint8_t page_num, std::vector<uint8_t> &write_data);
272 uint8_t write_mifare_ultralight_tag_(std::vector<uint8_t> &uid, const std::shared_ptr<nfc::NdefMessage> &message);
273 uint8_t clean_mifare_ultralight_();
274
275 enum NfcTask : uint8_t {
280 } next_task_{EP_READ};
281
286
287 uint8_t error_count_{0};
288 uint8_t fail_count_{0};
291 uint32_t tag_ttl_{250};
292
294 GPIOPin *irq_pin_{nullptr};
295 GPIOPin *ven_pin_{nullptr};
297
300
301 std::vector<DiscoveredEndpoint> discovered_endpoint_;
302
306
307 std::shared_ptr<nfc::NdefMessage> card_emulation_message_;
308 std::shared_ptr<nfc::NdefMessage> next_task_message_to_write_;
309
310 std::vector<nfc::NfcOnTagTrigger *> triggers_ontag_;
311 std::vector<nfc::NfcOnTagTrigger *> triggers_ontagremoved_;
312};
313
314} // namespace pn7160
315} // namespace esphome
uint8_t auth_mifare_classic_block_(uint8_t block_num, uint8_t key_num, const uint8_t *key)
uint8_t write_mifare_ultralight_page_(uint8_t page_num, std::vector< uint8_t > &write_data)
virtual uint8_t write_nfcc(nfc::NciMessage &tx)=0
float get_setup_priority() const override
Definition pn7160.h:164
void process_rf_deactivate_oid_(nfc::NciMessage &rx)
Definition pn7160.cpp:957
uint8_t send_init_config_()
Definition pn7160.cpp:303
void set_ven_pin(GPIOPin *ven_pin)
Definition pn7160.h:169
uint8_t selecting_endpoint_
Definition pn7160.h:290
void process_rf_discover_oid_(nfc::NciMessage &rx)
Definition pn7160.cpp:930
void loop() override
Definition pn7160.cpp:40
CallbackManager< void()> on_finished_write_callback_
Definition pn7160.h:299
uint8_t write_endpoint_(std::vector< uint8_t > &uid, std::shared_ptr< nfc::NdefMessage > &message)
Definition pn7160.cpp:529
void nci_fsm_set_state_(NCIState new_state)
set new controller state
Definition pn7160.cpp:704
void set_tag_write_message(std::shared_ptr< nfc::NdefMessage > message)
Definition pn7160.cpp:137
uint8_t read_mifare_classic_tag_(nfc::NfcTag &tag)
std::vector< nfc::NfcOnTagTrigger * > triggers_ontagremoved_
Definition pn7160.h:311
bool is_mifare_ultralight_formatted_(const std::vector< uint8_t > &page_3_to_6)
void process_data_message_(nfc::NciMessage &rx)
Definition pn7160.cpp:985
void dump_config() override
Definition pn7160.cpp:28
uint8_t sect_to_auth_(uint8_t block_num)
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig)
Definition pn7160.h:185
void erase_tag_(uint8_t tag_index)
Definition pn7160.cpp:589
uint8_t format_endpoint_(std::vector< uint8_t > &uid)
Definition pn7160.cpp:513
CardEmulationState ce_state_
Definition pn7160.h:303
uint8_t wait_for_irq_(uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool pin_state=true)
Definition pn7160.cpp:1154
uint8_t start_discovery_()
Definition pn7160.cpp:394
void nci_fsm_transition_()
advance controller state as required
Definition pn7160.cpp:602
uint8_t read_mifare_ultralight_tag_(nfc::NfcTag &tag)
optional< size_t > find_tag_uid_(const std::vector< uint8_t > &uid)
Definition pn7160.cpp:562
uint8_t read_endpoint_data_(nfc::NfcTag &tag)
Definition pn7160.cpp:477
uint8_t transceive_(nfc::NciMessage &tx, nfc::NciMessage &rx, uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool expect_notification=true)
Definition pn7160.cpp:1098
uint8_t stop_discovery_()
Definition pn7160.cpp:435
bool tag_emulation_enabled()
Definition pn7160.h:178
uint8_t find_mifare_ultralight_ndef_(const std::vector< uint8_t > &page_3_to_6, uint8_t &message_length, uint8_t &message_start_index)
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 pn7160.cpp:712
uint8_t clean_endpoint_(std::vector< uint8_t > &uid)
Definition pn7160.cpp:497
uint8_t write_mifare_classic_block_(uint8_t block_num, std::vector< uint8_t > &data)
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig)
Definition pn7160.h:184
uint8_t write_mifare_ultralight_tag_(std::vector< uint8_t > &uid, const std::shared_ptr< nfc::NdefMessage > &message)
void process_rf_intf_activated_oid_(nfc::NciMessage &rx)
Definition pn7160.cpp:817
void set_irq_pin(GPIOPin *irq_pin)
Definition pn7160.h:168
uint8_t set_discover_map_()
Definition pn7160.cpp:367
std::unique_ptr< nfc::NfcTag > build_tag_(uint8_t mode_tech, const std::vector< uint8_t > &data)
Definition pn7160.cpp:545
uint32_t last_nci_state_change_
Definition pn7160.h:289
void set_wkup_req_pin(GPIOPin *wkup_req_pin)
Definition pn7160.h:170
virtual uint8_t read_nfcc(nfc::NciMessage &rx, uint16_t timeout)=0
NCIState nci_state_error_
Definition pn7160.h:305
void set_tag_ttl(uint32_t ttl)
Definition pn7160.h:172
std::shared_ptr< nfc::NdefMessage > next_task_message_to_write_
Definition pn7160.h:308
enum esphome::pn7160::PN7160::NfcTask EP_READ
void add_on_emulated_tag_scan_callback(std::function< void()> callback)
Definition pn7160.h:187
void setup() override
Definition pn7160.cpp:15
uint8_t read_mifare_ultralight_bytes_(uint8_t start_page, uint16_t num_bytes, std::vector< uint8_t > &data)
CallbackManager< void()> on_emulated_tag_scan_callback_
Definition pn7160.h:298
void add_on_finished_write_callback(std::function< void()> callback)
Definition pn7160.h:191
uint8_t deactivate_(uint8_t type, uint16_t timeout=NFCC_DEFAULT_TIMEOUT)
Definition pn7160.cpp:437
GPIOPin * wkup_req_pin_
Definition pn7160.h:296
std::vector< DiscoveredEndpoint > discovered_endpoint_
Definition pn7160.h:301
uint8_t send_core_config_()
Definition pn7160.cpp:323
std::vector< nfc::NfcOnTagTrigger * > triggers_ontag_
Definition pn7160.h:310
void set_tag_emulation_message(std::shared_ptr< nfc::NdefMessage > message)
Definition pn7160.cpp:45
uint8_t set_listen_mode_routing_()
Definition pn7160.cpp:381
uint8_t refresh_core_config_()
Definition pn7160.cpp:346
void card_emu_t4t_get_response_(std::vector< uint8_t > &response, std::vector< uint8_t > &ndef_response)
Definition pn7160.cpp:1006
std::shared_ptr< nfc::NdefMessage > card_emulation_message_
Definition pn7160.h:307
GPIOPin * dwl_req_pin_
Definition pn7160.h:293
uint8_t reset_core_(bool reset_config, bool power)
Definition pn7160.cpp:224
uint8_t write_mifare_classic_tag_(const std::shared_ptr< nfc::NdefMessage > &message)
void process_message_()
parse & process incoming messages from the NFCC
Definition pn7160.cpp:729
void set_dwl_req_pin(GPIOPin *dwl_req_pin)
Definition pn7160.h:167
uint8_t read_mifare_classic_block_(uint8_t block_num, std::vector< uint8_t > &data)
uint8_t set_test_mode(TestMode test_mode, const std::vector< uint8_t > &data, std::vector< uint8_t > &result)
Definition pn7160.cpp:163
uint8_t type
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:19
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::unique_ptr< nfc::NfcTag > tag
Definition pn7160.h:156