12static constexpr uint8_t SEL_CMDS[] = {0x93, 0x95, 0x97};
15static const uint8_t NFCA_PROFILE_RX[][2] PROGMEM = {
20static const uint8_t NFCA_PROFILE_TX[][2]
PROGMEM = {
35static const uint8_t NFCA_PROFILE_CORR[][2]
PROGMEM = {
108 for (
size_t i = 0; i <
count; i++)
126 bool tx_done =
false;
128 while (
millis() - start < timeout_ms) {
138 uint8_t to_read = std::min<uint8_t>(resp_cap - resp_len, f1);
139 this->
read_fifo(resp + resp_len, to_read);
141 if (resp_len >= resp_cap)
196 this->
read_fifo(tmp, std::min<uint8_t>(f1,
sizeof(tmp)));
211 if (bcc != resp[4]) {
212 ESP_LOGV(TAG,
"Anticollision BCC mismatch");
216 uint8_t sel_pk[7] = {SEL_CMDS[this->
cascade_level_], 0x70, resp[0], resp[1], resp[2], resp[3], bcc};
219 const uint8_t *uid_part = resp[0] == 0x88 ? resp + 1 : resp;
220 const uint8_t *uid_end = resp + 4;
221 for (; uid_part < uid_end && this->
scan_uid_.
size() < nfc::NFC_UID_MAX_LENGTH; uid_part++)
228 if (!this->
transceive_ex_(sel_pk,
sizeof(sel_pk), sak_buf,
sizeof(sak_buf), sak_len, 150)) {
229 ESP_LOGW(TAG,
"SELECT failed (no SAK)");
233 uint8_t sak = sak_buf[0];
238 ESP_LOGE(TAG,
"Too many cascade levels");
249 if (uid_len != 4 && uid_len != 7 && uid_len != 10) {
250 ESP_LOGW(TAG,
"Discarding invalid UID len=%u",
static_cast<unsigned>(uid_len));
255#ifdef ESPHOME_LOG_HAS_VERBOSE
256 char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
278 std::equal(uid.begin(), uid.end(), this->scan_uid_.begin())) {
292 char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
294 ESP_LOGI(TAG,
"Tag detected: %s", uid_buf);
297#ifdef NFC_TAG_LISTENER_COUNT
304 char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
306 ESP_LOGI(TAG,
"Tag removed: %s", uid_buf);
309#ifdef NFC_TAG_LISTENER_COUNT
318 uint8_t chip_type = ic_identity & 0xF8;
319 if (chip_type != 0x28 && chip_type != 0x30) {
320 ESP_LOGE(TAG,
"IC identity mismatch: expected 0x28/0x30, got 0x%02X", chip_type);
326 const bool is_b_version = chip_type == 0x30;
327 ESP_LOGI(TAG,
"IC: 0x%02X (ST25R3916%s)", ic_identity, is_b_version ? LOG_STR_LITERAL(
"B") : LOG_STR_LITERAL(
""));
342 uint16_t vdd_mv = (uint16_t) vdd_raw * 23U + (((uint16_t) vdd_raw * 4U + 5U) / 10U);
343 sup3v = (vdd_mv < 3600);
344 ESP_LOGI(TAG,
"VDD: %u mV (sup3V=%s)", vdd_mv, sup3v ? LOG_STR_LITERAL(
"3.3V") : LOG_STR_LITERAL(
"5V"));
387 LOG_PIN(
" IRQ Pin: ", this->
irq_pin_);
389 LOG_UPDATE_INTERVAL(
this);
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void mark_failed()
Mark this component as failed.
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void enable_loop()
Enable this component's loop.
void disable_loop()
Disable this component's loop.
virtual void digital_write(bool value)=0
void push_back(const T &value)
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
StaticVector< NfcTagListener *, NFC_TAG_LISTENER_COUNT > tag_listeners_
uint32_t last_state_change_
void write_register_table_(const uint8_t(*table)[2], size_t count)
virtual void read_fifo(uint8_t *data, size_t len)=0
bool tag_found_this_scan_
static constexpr uint8_t IRQ_COL
static constexpr uint8_t IRQ_RXE
static constexpr uint8_t MISS_THRESHOLD
static constexpr uint8_t IRQ_TXE
virtual void write_command(uint8_t command)=0
LazyCallbackManager< void(const std::string &, const nfc::NfcTag &)> on_tag_callback_
bool transceive_ex_(const uint8_t *data, size_t len, uint8_t *resp, uint8_t resp_cap, uint8_t &resp_len, uint32_t timeout_ms)
void send_anticol_frame_()
virtual void write_register(uint8_t reg, uint8_t value)=0
static constexpr uint32_t FIELD_GUARD_MS
virtual void write_fifo(const uint8_t *data, size_t len)=0
LazyCallbackManager< void(const std::string &, const nfc::NfcTag &)> on_tag_removed_callback_
void dump_config() override
virtual uint8_t read_register(uint8_t reg)=0
InternalGPIOPin * irq_pin_
static void isr(ST25R *arg)
std::unique_ptr< nfc::NfcTag > current_tag_
constexpr float BME680_GAS_LOOKUP_TABLE_1[16] PROGMEM
char * format_uid_to(char *buffer, std::span< const uint8_t > uid)
Format UID to buffer with '-' separator (e.g., "04-11-22-33"). Returns buffer for inline use.
ESPHOME_LOG_TAG(TAG, "st25r")
@ ST25R_REG_UNDERSHOOT_CONF2
@ ST25R_REG_FIELD_THRESHOLD_DEACTV
@ ST25R_REG_NUM_TX_BYTES2
@ ST25R_REG_UNDERSHOOT_CONF1
@ ST25R_REG_PASSIVE_TARGET
@ ST25R_REG_OVERSHOOT_CONF1
@ ST25R_REG_TX_DRIVER_CONF
@ ST25R_REG_OVERSHOOT_CONF2
@ ST25R_REG_REGULATOR_CONTROL
@ ST25R_REG_NUM_TX_BYTES1
@ ST25R_REG_AD_CONV_RESULT
@ ST25R_REG_FIELD_THRESHOLD_ACTV
@ ST25R_REG_ISO14443A_CONF
@ ST25R_CMD_TRANSMIT_WUPA
@ ST25R_CMD_TRANSMIT_WITHOUT_CRC
@ ST25R_CMD_TRANSMIT_WITH_CRC
@ ST25R_CMD_ADJUST_REGULATORS
@ ST25R_CMD_RESET_RX_GAIN
constexpr uint8_t xor_bytes(const uint8_t *data, size_t len, uint8_t init=0)
XOR the bytes of data with size len, starting from init.
void HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
uint8_t progmem_read_byte(const uint8_t *addr)