diff --git a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp index 516bf57..33c04e0 100644 --- a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp +++ b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp @@ -266,7 +266,6 @@ void loop() write_ndef(); } M5.Log.printf("Please remove the PICC from the reader\n"); - } else { M5.Speaker.tone(1000, 50); M5.Log.printf("Not support the NDEF\n"); diff --git a/src/nfc/a/nfca.hpp b/src/nfc/a/nfca.hpp index 512b326..6f4f627 100644 --- a/src/nfc/a/nfca.hpp +++ b/src/nfc/a/nfca.hpp @@ -438,14 +438,14 @@ enum class Command : uint8_t { ///@name Timeout ///@{ constexpr uint32_t TIMEOUT_REQ_WUP{4}; // 4 -constexpr uint32_t TIMEOUT_SELECT{4}; // 4 +constexpr uint32_t TIMEOUT_SELECT{8}; // 4 constexpr uint32_t TIMEOUT_ANTICOLL{8}; // 8 constexpr uint32_t TIMEOUT_HALT{2}; constexpr uint32_t TIMEOUT_GET_VERSION{5}; // 5 constexpr uint32_t TIMEOUT_3DES{10}; constexpr uint32_t TIMEOUT_AUTH1{2}; constexpr uint32_t TIMEOUT_AUTH2{10}; -constexpr uint32_t TIMEOUT_READ{4}; +constexpr uint32_t TIMEOUT_READ{12}; constexpr uint32_t TIMEOUT_FAST_READ{2}; constexpr uint32_t TIMEOUT_FAST_READ_4PAGE{4}; // 3.7 constexpr uint32_t TIMEOUT_FAST_READ_12PAGE{4}; // 3.7 diff --git a/src/nfc/layer/a/emulation_layer_a.cpp b/src/nfc/layer/a/emulation_layer_a.cpp index 02b4f63..e37ec1a 100644 --- a/src/nfc/layer/a/emulation_layer_a.cpp +++ b/src/nfc/layer/a/emulation_layer_a.cpp @@ -53,7 +53,6 @@ bool EmulationLayerA::begin(const m5::nfc::a::PICC& picc, uint8_t* ptr, const ui return (_state != State::None); } - bool EmulationLayerA::end() { if (_state == State::None) { @@ -74,23 +73,23 @@ void EmulationLayerA::update() case State::None: break; case State::Off: - // if (_state != _prev) M5_LIB_LOGE("==OFF"); + if (_state != _prev) M5_LIB_LOGE("==OFF"); update_off(); break; case State::Idle: - // if (_state != _prev) M5_LIB_LOGE("==IDLE"); + if (_state != _prev) M5_LIB_LOGE("==IDLE"); update_idle(); break; case State::Ready: - // if (_state != _prev) M5_LIB_LOGE("==READY"); + if (_state != _prev) M5_LIB_LOGE("==READY"); update_ready(); break; case State::Active: - // if (_state != _prev) M5_LIB_LOGE("==ACTIVE"); + if (_state != _prev) M5_LIB_LOGE("==ACTIVE"); update_active(); break; case State::Halt: - // if (_state != _prev) M5_LIB_LOGE("==HALT"); + if (_state != _prev) M5_LIB_LOGE("==HALT"); update_halt(); break; default: @@ -183,7 +182,7 @@ EmulationLayerA::State EmulationLayerA::receive_callback(const uint8_t* rx, cons break; default: - M5_LIB_LOGE("cmd:%02X %u", rx[0], rx_len); + M5_LIB_LOGE("CMD:%02X %u", rx[0], rx_len); break; } // M5_LIB_LOGE(" --> %u", ret); diff --git a/src/nfc/layer/nfc_layer_a.cpp b/src/nfc/layer/nfc_layer_a.cpp index 6749cf3..69a9ef7 100644 --- a/src/nfc/layer/nfc_layer_a.cpp +++ b/src/nfc/layer/nfc_layer_a.cpp @@ -193,20 +193,18 @@ bool NFCLayerA::reactivate(const PICC& picc) PICC tmp = picc; uint16_t discard{}; if (deactivate()) { - // m5::utility::delay(2); // guard time (ULC) -#if 0 - // return wakeup(discard) && activate(tmp); -#else + m5::utility::delay(2); // FDT if (!wakeup(discard)) { M5_LIB_LOGE("Failed to wakeup"); return false; } + m5::utility::delay(2); // FDT if (!activate(tmp)) { M5_LIB_LOGE("Failed to activate"); return false; } + // m5::utility::delay(1); // FDT return true; -#endif } M5_LIB_LOGD("Failed to deactivate"); return false; @@ -277,7 +275,6 @@ bool NFCLayerA::identify_picc(m5::nfc::a::PICC& picc) } // The PICC goes idle when sending an external command, so select again if (!reactivate(picc)) { - M5_LIB_LOGE(">>>> ERR3"); return false; } // Try ULC Auth diff --git a/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp b/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp index c3a487d..099d445 100644 --- a/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp +++ b/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp @@ -22,6 +22,8 @@ using namespace m5::nfc::a; using namespace m5::nfc::a::mifare; using namespace m5::nfc::a::mifare::classic; +#pragma GCC optimize("O3") + namespace { inline bool is_eof(const uint32_t irq) { @@ -275,6 +277,7 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_idle() _u.set_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx); if (_layer.state() == EmulationLayerA::State::Active && !_wakeup) { + // M5_LIB_LOGE("A->I"); _u.clear_bit_register8(REG_NFCIP_1_PASSIVE_TARGET_DEFINITION, d_106_ac_a); // Enable auto response for NFC-A _u.writeDirectCommand(CMD_GO_TO_SENSE); } @@ -284,6 +287,9 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_idle() // rfalCheckEnableObsModeRx(); _wakeup = false; + + _u.update(); + return update_idle(); return EmulationLayerA::State::Idle; } @@ -295,11 +301,12 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_ready() } _u.clear_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx); - _u.clear_bit_register8(REG_OPERATION_CONTROL, wu); // Disable wakeup mode _u.writeModeDefinition(mode_listen_nfc_a); // Disable birrate detection and collision _u.writeBitrate(_bitrate, _bitrate); + _u.update(); + return update_ready(); return EmulationLayerA::State::Ready; } @@ -311,32 +318,29 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_active() _u.enable_interrupts(I_rxe32); - /* - uint32_t m32{}; - _u.readMaskInterrupts(m32); - M5_LIB_LOGE("M:%08X", m32); - */ - + _u.update(); + return update_active(); return EmulationLayerA::State::Active; } EmulationLayerA::State ListenerST25R3916ForA::goto_halt() { _data_flag = false; + _u.clear_bit_register8(REG_NFCIP_1_PASSIVE_TARGET_DEFINITION, d_106_ac_a); // Enable auto response for NFC-A _u.writeDirectCommand(CMD_GO_TO_SLEEP); - _u.change_bit_register8(REG_MODE_DEFINITION, mode_bitrate_detection, mode_mask); + _u.clear_bit_register8(REG_ISO14443A_SETTINGS, nfc_f0); - - //_u.writeDirectCommand(CMD_CLEAR_FIFO); _u.writeDirectCommand(CMD_UNMASK_RECEIVE_DATA); - _u.enable_interrupts(I_nfct32 | I_rxs32 | I_crc32 | I_err132 | I_err232 | I_par32 | I_eon32 | I_eof32 | mode_irq); if (!is_extra_field()) { return goto_off(); } + + _u.update(); + return update_halt(); return EmulationLayerA::State::Halt; } @@ -413,7 +417,7 @@ EmulationLayerA::State ListenerST25R3916ForA::update_idle() if ((irq32 & I_rxe_pta32) && _bitrate == Bitrate::Bps106K) { uint8_t pta{}; if (_u.readPassiveTargetDisplay(pta) && ((pta & 0x0F) > pta_state_idle)) { - // M5_LIB_LOGE("PTA:%02X", pta); + // M5_LIB_LOGE(" I PTA:%02X", pta); return goto_ready(); } // M5_LIB_LOGE("PTA:%02X", pta); @@ -494,13 +498,9 @@ EmulationLayerA::State ListenerST25R3916ForA::update_halt() return EmulationLayerA::State::Halt; } - static uint32_t latest = 0; - if (latest != irq32) { - latest = irq32; - } - // initiator bit rate was recognized if ((irq32 & I_nfct32) && _bitrate == Bitrate::Invalid) { + // M5_LIB_LOGE(" >> BR"); uint8_t br{}; _u.readBitrateDetectionDisplay(br); br = (br >> 4) & 0x03; // 0:106 1:212 2:424 3:848 @@ -510,9 +510,11 @@ EmulationLayerA::State ListenerST25R3916ForA::update_halt() _bitrate = static_cast(br); } if (is_eof(irq32)) { + // M5_LIB_LOGE(" >> OFF"); return goto_off(); } if ((irq32 & I_rxe32) && _bitrate != Bitrate::Invalid) { + // M5_LIB_LOGE(" >> RX"); _u.writeDirectCommand(CMD_CLEAR_FIFO); _u.writeDirectCommand(CMD_UNMASK_RECEIVE_DATA); return EmulationLayerA::State::Halt; @@ -520,6 +522,7 @@ EmulationLayerA::State ListenerST25R3916ForA::update_halt() if ((irq32 & I_rxe_pta32) && _bitrate == Bitrate::Bps106K) { uint8_t pta{}; if (_u.readPassiveTargetDisplay(pta) && ((pta & 0x0F) > pta_state_halt)) { + // M5_LIB_LOGE(" H PTA:%02X", pta); _wakeup = true; return goto_ready(); } diff --git a/src/nfc/layer/unit/nfc_layer_a_ST25R3916.cpp b/src/nfc/layer/unit/nfc_layer_a_ST25R3916.cpp index af0ba9e..6eb4980 100644 --- a/src/nfc/layer/unit/nfc_layer_a_ST25R3916.cpp +++ b/src/nfc/layer/unit/nfc_layer_a_ST25R3916.cpp @@ -18,6 +18,8 @@ using namespace m5::nfc::a; using namespace m5::nfc::a::mifare; using namespace m5::nfc::a::mifare::classic; +#pragma GCC optimize ("O3") + namespace m5 { namespace nfc { // diff --git a/src/unit/ST25R3916_definition.hpp b/src/unit/ST25R3916_definition.hpp index ceb1d22..b8ad10c 100644 --- a/src/unit/ST25R3916_definition.hpp +++ b/src/unit/ST25R3916_definition.hpp @@ -280,17 +280,37 @@ constexpr uint8_t d_106_ac_a{0x01}; // 0x0A Auxiliary definition register constexpr uint8_t no_crc_rx{0x80}; +constexpr uint8_t dis_corr{0x04}; constexpr uint8_t nfc_n1{0x02}; constexpr uint8_t nfc_n0{0x01}; constexpr uint8_t nfc_n_mask{0x03}; +// 0x0B Receiver configuration register 1 +constexpr uint8_t ch_sel{0x80}; +constexpr uint8_t z_600k{0x08}; +constexpr uint8_t h200{0x04}; +constexpr uint8_t h80{0x02}; +constexpr uint8_t z12k{0x01}; + +// 0x0C Receiver configuration register 2 +constexpr uint8_t sqm_dyn{0x20}; // Automatic squelch activation after end of TX +constexpr uint8_t puz_61{0x10}; // Select squelch trigger level. +constexpr uint8_t agc_en{0x08}; // AGC enabled +constexpr uint8_t agc_m{0x04}; // AGC operates during complete receive period +constexpr uint8_t agc6_3{0x01}; // AGC ratio 0:3 1:6 + // 0x12 Timer and EMV control register constexpr uint8_t mrt_step{0x08}; // Mask receive timer step size 0:64/fc, 1:5126/fc constexpr uint8_t nrt_nfc{0x01}; // No-response timer start condition in AP2P initiator and target mode. constexpr uint8_t nrt_emv{0x01}; // 1: No-response timer EMV mode constexpr uint8_t nrt_step{0x01}; // No-response timer step size 0:64/fc, 1:4096/fc +constexpr uint8_t nrt_gptc_none{0x00}; +constexpr uint8_t nrt_gptc_erx{0x01 << 5}; // Additionally starts at End of RX (after EOF) +constexpr uint8_t nrt_gptc_srx{0x02 << 5}; // Additionally starts at Start of RX +constexpr uint8_t nrt_gptc_etx{0x03 << 5}; // Additionally starts at End of TX + // 0x1A Main interrupt register constexpr uint8_t I_osc{0x80}; // IRQ when oscillator frequency is stable constexpr uint8_t I_wl{0x40}; // IRQ due to FIFO water level @@ -299,6 +319,7 @@ constexpr uint8_t I_rxe{0x10}; // IRQ due to end of receive constexpr uint8_t I_txe{0x08}; // IRQ due to end of transmission constexpr uint8_t I_col{0x04}; // IRQ due to bit collision constexpr uint8_t I_rx_rest{0x02}; // 1: Mask IRQ due to automatic reception restart +// 0x00 RFU constexpr uint32_t I_osc32 = ((uint32_t)I_osc << 24); constexpr uint32_t I_wl32 = ((uint32_t)I_wl << 24); @@ -411,6 +432,8 @@ inline bool is_irq32_collision(const uint32_t irq32) uint8_t calculate_mrt(const uint32_t us, const bool mrt_step /* false:64, true:512*/); uint16_t calculate_nrt(const uint32_t ms, const bool nrt_step /* false:64, true:4096*/); +inline uint8_t calculate_fdt(const uint32_t us); + } // namespace st25r3916 diff --git a/src/unit/unit_ST25R3916.cpp b/src/unit/unit_ST25R3916.cpp index 422944c..de1d17c 100644 --- a/src/unit/unit_ST25R3916.cpp +++ b/src/unit/unit_ST25R3916.cpp @@ -23,6 +23,8 @@ using namespace m5::nfc::a; using namespace m5::nfc::a::mifare; using namespace m5::nfc::a::mifare::classic; +#pragma GCC optimize("O3") + namespace { // HackerCap <-> CardputerADV pin configurations (EXT 2.54-14P) constexpr int PIN_SCK{40}; // G40 @@ -364,7 +366,8 @@ bool UnitST25R3916::nfc_initial_field_on() clearInterrupts(); mask &= ~(I_cac32 | I_cat32 | I_apon32); - writeMaskInterrupts(mask); + // writeMaskInterrupts(mask); + disable_interrupts(mask); return ret && modify_bit_register8(REG_OPERATION_CONTROL, tx_en | rx_en, 0x00); #endif @@ -594,10 +597,9 @@ uint32_t UnitST25R3916::wait_for_interrupt(const uint32_t irq, const uint32_t ti return flags | I_nre32; // Timeout } #else -uint32_t UnitST25R3916::wait_for_interrupt(const uint32_t irq, const uint32_t timeout_ms) +uint32_t UnitST25R3916::wait_for_interrupt(const uint32_t bits, const uint32_t timeout_ms) { auto timeout_at = m5::utility::millis() + timeout_ms; - uint32_t flags{}; do { if (!_using_irq || _interrupt_occurred) { _interrupt_occurred = false; @@ -606,14 +608,15 @@ uint32_t UnitST25R3916::wait_for_interrupt(const uint32_t irq, const uint32_t ti _stored_irq |= v; } } - if (_stored_irq & irq) { - return _stored_irq; + uint32_t irq32 = _stored_irq & bits; + if (irq32) { + _stored_irq &= ~irq32; + return irq32; } std::this_thread::yield(); } while (m5::utility::millis() <= timeout_at); return _stored_irq | I_nre32; // Timeout } - #endif bool UnitST25R3916::wait_for_FIFO(const uint32_t timeout_ms, const uint16_t required_size) @@ -648,7 +651,7 @@ bool UnitST25R3916::wait_for_FIFO(const uint32_t timeout_ms, const uint16_t requ return false; } -bool UnitST25R3916::write_noresponse_timeout(const uint32_t ms) +bool UnitST25R3916::write_fwt_timer(const uint32_t ms) { uint8_t timer_ctrl{}; if (readTimerAndEMVControl(timer_ctrl)) { diff --git a/src/unit/unit_ST25R3916.hpp b/src/unit/unit_ST25R3916.hpp index 7db2b80..c73448b 100644 --- a/src/unit/unit_ST25R3916.hpp +++ b/src/unit/unit_ST25R3916.hpp @@ -2145,7 +2145,7 @@ protected: bool write_register32(const uint8_t reg, const uint32_t v); bool write_register32(const uint16_t reg, const uint32_t v); - bool write_noresponse_timeout(const uint32_t ms); + bool write_fwt_timer(const uint32_t ms); bool write_mask_receiver_timer(const uint32_t us); bool write_squelch_timer(const uint32_t us); @@ -2235,12 +2235,15 @@ protected: private: config_t _cfg{}; + volatile uint32_t _stored_irq{}; uint32_t _mask_irq{0xFFFFFFFF}; // for !_using_irq + + volatile bool _interrupt_occurred{}; m5::nfc::NFC _nfcMode{}; bool _encrypted{}; bool _using_irq{}; - volatile bool _interrupt_occurred{}; + m5::nfc::a::mifare::classic::Crypto1 _crypto1{}; }; diff --git a/src/unit/unit_ST25R3916_nfca.cpp b/src/unit/unit_ST25R3916_nfca.cpp index 5d0f3cd..c2b3b0f 100644 --- a/src/unit/unit_ST25R3916_nfca.cpp +++ b/src/unit/unit_ST25R3916_nfca.cpp @@ -21,6 +21,8 @@ using namespace m5::nfc::a; using namespace m5::nfc::a::mifare; using namespace m5::nfc::a::mifare::classic; +#pragma GCC optimize("O3") + #define CHECK_MODE() \ do { \ if (!isNFCMode(NFC::A)) { \ @@ -120,26 +122,42 @@ bool UnitST25R3916::configure_nfc_a() { _encrypted = false; -#if 0 - // - // ISO14443A - // M5_LIB_LOGE(">>>>>> try ISO14443A REQA"); - writeInitiatorOperationMode(InitiatorOperationMode::ISO14443A, 0x01 /* nfc_ar01 */); - writeBitrate(Bitrate::Bps106K, Bitrate::FC128_106Kbits); - writeSettingsISO14443A(0x0); -#endif - - if (!writeInitiatorOperationMode(InitiatorOperationMode::ISO14443A, nfc_ar8_auto) || // - !writeBitrate(Bitrate::Bps106K, Bitrate::Bps106K) || // + if (!writeInitiatorOperationMode(InitiatorOperationMode::ISO14443A, nfc_ar8_auto /* 0x01 */) || // + !writeBitrate(Bitrate::Bps106K, Bitrate::Bps106K) || // !writeSettingsISO14443A(0x00)) { return false; } - return writeReceiverConfiguration1(0x08) && // z600k - writeReceiverConfiguration2(0x2D) && // sqm_dyn , agc_en, agc_m, agc6_3, - writeReceiverConfiguration3(0x00) && // - writeReceiverConfiguration4(0x00) && // - writeMaskInterrupts(0) && // + clear_bit_register8(REG_AUXILIARY_DEFINITION, dis_corr); + writeOvershootProtectionConfiguration1(0x40); + writeOvershootProtectionConfiguration2(0x03); + writeUndershootProtectionConfiguration1(0x40); + writeUndershootProtectionConfiguration2(0x03); + + writeCorrelatorConfiguration1(0x47); + writeCorrelatorConfiguration2(0x00); + +#if 1 + // Sensitivity Priority + constexpr uint8_t recv_3{0x00}; + constexpr uint8_t recv_4{0x00}; +#else + // Stability-focused + constexpr uint8_t recv_3{0xD8}; + constexpr uint8_t recv_4{0x22}; + // Intermediate Settings + constexpr uint8_t recv_3{0x80}; + constexpr uint8_t recv_4{0x11}; +#endif + + enable_interrupts(I_wl32 | I_txe32 | I_rxs32 | I_rxe32 | I_par32 | I_crc32 | I_err132 | I_err232 | I_nre32 | + I_col32); + + return writeReceiverConfiguration1(z_600k) && // z600k + writeReceiverConfiguration2(sqm_dyn | agc_en | agc_m | agc6_3) && // + writeReceiverConfiguration3(recv_3) && // rx gain + writeReceiverConfiguration4(recv_4) && // rx gain + writeDirectCommand(CMD_RESET_RX_GAIN) && writeMaskInterrupts(0) && // nfc_initial_field_on(); } @@ -209,7 +227,7 @@ uint32_t UnitST25R3916::nfcaTransceive(uint8_t* rx, uint16_t& rx_len, const uint } // m5::utility::log::dump(tx, tx_len, false); - if ((timeout_ms ? !write_noresponse_timeout(timeout_ms) : false) || // + if ((timeout_ms ? !write_fwt_timer(timeout_ms) : false) || // !writeSettingsISO14443A(0x00 /*standard*/) || !clear_bit_register8(REG_AUXILIARY_DEFINITION,no_crc_rx) || // !clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || !writeFIFO(tx, tx_len) || !writeNumberOfTransmittedBytes(tx_len, 0) || !writeDirectCommand(CMD_TRANSMIT_WITH_CRC)) { @@ -244,7 +262,7 @@ bool UnitST25R3916::nfcaTransmit(const uint8_t* tx, const uint16_t tx_len, const return false; } - if ((timeout_ms ? !write_noresponse_timeout(timeout_ms) : false) || // + if ((timeout_ms ? !write_fwt_timer(timeout_ms) : false) || // !writeSettingsISO14443A(0x00 /*standard*/) || !clear_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx) || // !clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || !writeFIFO(tx, tx_len) || // !writeNumberOfTransmittedBytes(tx_len, 0) || !writeDirectCommand(CMD_TRANSMIT_WITH_CRC)) { @@ -264,7 +282,7 @@ bool UnitST25R3916::nfcaReceive(uint8_t* rx, uint16_t& rx_len, const uint32_t ti } if (!wait_for_FIFO(timeout_ms, rx_len_org)) { - M5_LIB_LOGE("Timeout"); + M5_LIB_LOGD("Timeout"); return false; } @@ -287,16 +305,15 @@ bool UnitST25R3916::nfca_request_wakeup(uint16_t& atqa, const bool request) atqa = 0; // REQA or WUPA (Receive without CRC) - if (!write_noresponse_timeout(TIMEOUT_REQ_WUP) || // + if (!write_fwt_timer(TIMEOUT_REQ_WUP) || // !writeSettingsISO14443A(antcl) || !set_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx) || - // writeMaskMainInterrupt(mask) && writeMaskTimerAndNFCInterrupt(~I_nre) &&// !clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || !writeDirectCommand(request ? CMD_TRANSMIT_REQA : CMD_TRANSMIT_WUPA)) { M5_LIB_LOGE("Failed to %s", request ? "REQA" : "WUPA"); return false; } - auto irq = wait_for_interrupt(I_rxe32 | I_rxs | I_col32, TIMEOUT_REQ_WUP); + auto irq = wait_for_interrupt(I_rxe32 | I_rxs32 | I_col32, TIMEOUT_REQ_WUP); // M5_LIB_LOGE("IRQ:%08X", irq); if (!is_irq32_rxe(irq) && is_irq32_rxs(irq)) { @@ -342,7 +359,7 @@ bool UnitST25R3916::nfca_anti_collision(uint8_t rbuf[5], const uint8_t lv) } // ANTICOLL/SEL - if (!write_noresponse_timeout(TIMEOUT_ANTICOLL) || // + if (!write_fwt_timer(TIMEOUT_ANTICOLL) || // !writeSettingsISO14443A(antcl) || !clear_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx)) { return false; } @@ -440,6 +457,7 @@ bool UnitST25R3916::nfcaSelectWithAnticollision(bool& completed, PICC& picc, con // M5_LIB_LOGE(">>>> SAK:%02X (%u, %u) %u ", // // sak, is_sak_completed(sak), is_sak_completed_14443_4(sak), sak_to_type(sak)); + // Completed? if (is_sak_completed_14443_4(sak)) { picc.size = 1 + lv * 3; picc.sak = sak; @@ -449,39 +467,7 @@ bool UnitST25R3916::nfcaSelectWithAnticollision(bool& completed, PICC& picc, con completed = true; return true; } -#if 0 - ATS ats{}; - // RATS - if (!iso144434RequestATS(ats)) { - return false; - } - picc.size = 1 + lv * 3; - picc.sak = sak; - // GetVersion(L4) - uint8_t ver[8]{}; - if (mifare_get_version4(ver)) { - picc.type = version4_to_type(picc.sub_type, ver); - picc.blocks = get_number_of_blocks(picc.type); - } else { - // Check historical bytes - //m5::utility::log::dump(ats.header, sizeof(ats.header), false); - //m5::utility::log::dump(ats.historical.data(), ats.historical_len, false); - picc.type = - historical_bytes_to_type_sak20(picc.sub_type, ats.historical.data(), ats.historical_len, picc.atqa); - picc.blocks = get_number_of_blocks(picc.type); - completed = (picc.type != Type::Unknown); - } - if (!completed) { - picc.type = Type::ISO_14443_4; - // Need more CCile,SystemFile - completed = true; - } - return true; - } -#endif - - // Completed? if (is_sak_completed(sak)) { picc.size = 1 + lv * 3; picc.sak = sak; @@ -489,39 +475,6 @@ bool UnitST25R3916::nfcaSelectWithAnticollision(bool& completed, PICC& picc, con sak_to_type(sak); // WARNING: This is a preliminary diagnosis; a more accurate diagnosis is required picc.blocks = get_number_of_blocks(picc.type); completed = true; - // M5_LIB_LOGE(">>>> tmp type %s", picc.typeAsString().c_str()); - -#if 0 - // More detailed type identification - if (picc.type == Type::MIFARE_Ultralight) { - picc.type = Type::Unknown; - uint8_t ver[8]{}; - uint16_t discard{}; - // GetVersion(L3) - if (mifare_get_version3(ver)) { - picc.type = version3_to_type(ver); - } else { - // PICC is IDLE... so need reactivate - completed = nfcaWakeup(discard) && nfcaSelect(picc); - } - if (picc.type == Type::Unknown) { - uint8_t discard_ek[8]{}; - if (mifareUltralightCAuthenticate1(discard_ek)) { - // ULC has AUTH - picc.type = Type::MIFARE_UltralightC; - // Throw an Hlt to transition to IDLE - // Otherwise, subsequent commands become invalid in an incomplete state, causing unexpected IDLE - nfcaHlt(); - } else { - // really UL - picc.type = Type::MIFARE_Ultralight; - } - picc.blocks = get_number_of_blocks(picc.type); - // PICC is IDLE... so need reactivate - completed = nfcaWakeup(discard) && nfcaSelect(picc); - } - } -#endif } // M5_LIB_LOGE(">>>> Select %02X %u %u", sak, completed, has_sak_dependent_bit(sak)); return completed || has_sak_dependent_bit(sak); // completed or continue @@ -583,11 +536,11 @@ bool UnitST25R3916::nfcaHlt() const uint8_t hlt_frame[2] = {m5::stl::to_underlying(Command::HLTA), 0x00}; if (_encrypted) { - if (!write_noresponse_timeout(TIMEOUT_HALT) || !mifare_classic_send_encrypt(hlt_frame, sizeof(hlt_frame))) { + if (!write_fwt_timer(TIMEOUT_HALT) || !mifare_classic_send_encrypt(hlt_frame, sizeof(hlt_frame))) { return false; } } else { - if (!write_noresponse_timeout(TIMEOUT_HALT) || // + if (!write_fwt_timer(TIMEOUT_HALT) || // !writeSettingsISO14443A(0x00 /*standard*/) || !clear_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx) || // !clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || // @@ -908,7 +861,7 @@ bool UnitST25R3916::mifare_classic_authenticate(const Command cmd, const PICC& p writeDirectCommand(CMD_RESET_RX_GAIN); - if (!write_noresponse_timeout(TIMEOUT_AUTH2) || // + if (!write_fwt_timer(TIMEOUT_AUTH2) || // !writeSettingsISO14443A(no_tx_par) || !set_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx) || // !clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || // !writeFIFO(bitstream, sizeof(bitstream)) || !writeNumberOfTransmittedBytes(sizeof(bitstream), 0) || // @@ -1025,15 +978,14 @@ bool UnitST25R3916::mifareGetVersion4(uint8_t info[8]) uint16_t rx_len = 128; if (info && nfcaTransceive(rx, rx_len, cmd, sizeof(cmd), TIMEOUT_GET_VERSION)) { - //M5_LIB_LOGE(">>>> VER L4"); - //m5::utility::log::dump(rx, rx_len, false); + // M5_LIB_LOGE(">>>> VER L4"); + // m5::utility::log::dump(rx, rx_len, false); return true; } M5_LIB_LOGE(">>>> ERROR VER L4"); return false; } - // -------------------------------- For NTAG bool UnitST25R3916::ntagReadPage(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage) { diff --git a/src/unit/unit_ST25R3916_nfcb.cpp b/src/unit/unit_ST25R3916_nfcb.cpp index 70db52d..5e099d2 100644 --- a/src/unit/unit_ST25R3916_nfcb.cpp +++ b/src/unit/unit_ST25R3916_nfcb.cpp @@ -99,7 +99,7 @@ bool UnitST25R3916::nfcbTransmit(const uint8_t* tx, const uint16_t tx_len, const if (!tx || !tx_len) { return false; } - if (timeout_ms && !write_noresponse_timeout(timeout_ms)) { + if (timeout_ms && !write_fwt_timer(timeout_ms)) { return false; } diff --git a/src/unit/unit_ST25R3916_nfcf.cpp b/src/unit/unit_ST25R3916_nfcf.cpp index 0c2c80d..b35f490 100644 --- a/src/unit/unit_ST25R3916_nfcf.cpp +++ b/src/unit/unit_ST25R3916_nfcf.cpp @@ -111,7 +111,7 @@ bool UnitST25R3916::nfcfTransceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* return false; } - if (timeout_ms && !write_noresponse_timeout(timeout_ms)) { + if (timeout_ms && !write_fwt_timer(timeout_ms)) { return false; } diff --git a/src/unit/unit_ST25R3916_nfcv.cpp b/src/unit/unit_ST25R3916_nfcv.cpp index 5b5f24f..162f334 100644 --- a/src/unit/unit_ST25R3916_nfcv.cpp +++ b/src/unit/unit_ST25R3916_nfcv.cpp @@ -165,7 +165,7 @@ bool UnitST25R3916::nfcv_transmit(const uint8_t* tx, const uint16_t tx_len, cons //m5::utility::log::dump(frame.data(), frame.size(), false); // Send - if (timeout_ms && !write_noresponse_timeout(timeout_ms)) { + if (timeout_ms && !write_fwt_timer(timeout_ms)) { return false; } if (!clearInterrupts() || !writeDirectCommand(CMD_CLEAR_FIFO) || !writeFIFO(frame.data(), frame.size()) || diff --git a/src/unit/unit_ST25R3916_util.cpp b/src/unit/unit_ST25R3916_util.cpp index 5e4f578..f6c9e38 100644 --- a/src/unit/unit_ST25R3916_util.cpp +++ b/src/unit/unit_ST25R3916_util.cpp @@ -57,7 +57,7 @@ uint16_t calculate_nrt(const uint32_t ms, const bool nrt_step) uint64_t us = (uint64_t)ms * 1000u; uint64_t nrt = (us * FC_HZ + step_num - 1) / step_num; - return static_cast(std::max(std::min(nrt, 0xFFFFu), 1u)); + return static_cast(std::max(std::min(nrt, 0xFFFFu), 1u)); // 1-0xFFFF } uint8_t calculate_mrt(const uint32_t us, const bool mrt_step /* false:64, true:512*/) @@ -68,8 +68,16 @@ uint8_t calculate_mrt(const uint32_t us, const bool mrt_step /* false:64, true:5 const uint32_t step_num = mrt_step ? STEP512_NUM : STEP64_NUM; // mrt = ceil(us / step) uint32_t mrt = (us * FC_HZ + step_num - 1) / step_num; - return static_cast(std::max(std::min(mrt, 0xFFu), 4u)); + return static_cast(std::max(std::min(mrt, 0xFFu), 4u)); // 4-0xFF } + +inline uint8_t calculate_fdt(const uint32_t us) +{ + constexpr uint32_t FC_HZ{13560000}; + uint32_t ticks = (us * FC_HZ + 8000000 - 1) / 8000000; + return static_cast(std::max(std::min(ticks, 0xFFFFu), 1u)); // 1-0xFFFF +} + } // namespace st25r3916 bool UnitST25R3916::modify_bit_register8(const uint8_t reg, const uint8_t set_mask, const uint8_t clear_mask) @@ -156,7 +164,7 @@ bool UnitST25R3916::modify_interrupts(const uint32_t clr, const uint32_t set) uint32_t nv = (pv & ~clr) | set; if (pv == nv || writeMaskInterrupts(nv)) { - //M5_LIB_LOGE("%08X -> %08X/%08X -> %08X", pv, clr, set, nv); + // M5_LIB_LOGE("%08X -> %08X/%08X -> %08X", pv, clr, set, nv); return true; } return false;