mirror of
https://github.com/m5stack/M5Unit-NFC.git
synced 2026-05-20 11:48:34 -07:00
Fixes some issues, Add of per-file compilation options
This commit is contained in:
@@ -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");
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Bitrate>(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();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
//
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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{};
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()) ||
|
||||
|
||||
@@ -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<uint16_t>(std::max<uint64_t>(std::min<uint64_t>(nrt, 0xFFFFu), 1u));
|
||||
return static_cast<uint16_t>(std::max<uint64_t>(std::min<uint64_t>(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<uint8_t>(std::max<uint32_t>(std::min<uint32_t>(mrt, 0xFFu), 4u));
|
||||
return static_cast<uint8_t>(std::max<uint32_t>(std::min<uint32_t>(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<uint16_t>(std::max<uint32_t>(std::min<uint32_t>(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;
|
||||
|
||||
Reference in New Issue
Block a user