diff --git a/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp b/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp index c81b664..73d3bd5 100644 --- a/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp +++ b/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp @@ -43,18 +43,21 @@ m5::unit::HackerCapNFC unit{}; // HackerCap (SPI) #endif m5::nfc::EmulationLayerA emu_a{unit}; -// KeyA that can authenticate all blocks -// If it's a different key value, change it -constexpr Key keyA = DEFAULT_KEY; // Default as 0xFFFFFFFFFFFF +// constexpr Key keyA = DEFAULT_KEY; // Default as 0xFFFFFFFFFFFF +// constexpr Key keyB = DEFAULT_KEY; // Default as 0xFFFFFFFFFFFF PICC picc{}; -//#define EMU_MIFARE_ULTRALIGHT - #define EMU_NTAG213 +#define EMU_MIFARE_ULTRALIGHT +// HackerCap : iPhone, NFC tools, NFC Taginfo. NFC Tap +// Basic+I2C : iPhone, NFC Tap +// NG -> NFC tools, NFC Taginfo -#if defined(EMU_MIFARE_CLASSIC_1K) +// #define EMU_NTAG213 +// HackerCap : iPhone, NFC tools, NFC Taginfo. NFC Tap +// Basic+I2C : iPhone, NFC tools, NFC Taginfo. NFC Tap -#elif defined(EMU_MIFARE_ULTRALIGHT) +#if defined(EMU_MIFARE_ULTRALIGHT) constexpr Type type{Type::MIFARE_Ultralight}; constexpr uint8_t uid[] = {0x04, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE}; uint8_t picc_memory[] = { @@ -186,7 +189,7 @@ void setup() M5_LOGI("getPin: SDA:%u SCL:%u", pin_num_sda, pin_num_scl); Wire.end(); Wire.begin(pin_num_sda, pin_num_scl, 400 * 1000U); - + // Wire.begin(pin_num_sda, pin_num_scl, 1000 * 1000u); if (!Units.add(unit, Wire) || !Units.begin()) { M5_LOGE("Failed to begin"); lcd.clear(TFT_RED); @@ -221,38 +224,25 @@ void setup() lcd.setFont(&fonts::Font2); // - picc.emulate(type, uid, sizeof(uid)); // PICC information to emulate - if (picc.isMifareUltralight() || picc.isNTAG()) { + lcd.startWrite(); + lcd.fillScreen(TFT_RED); + if (picc.emulate(type, uid, sizeof(uid))) { embed_uid(picc_memory, uid); - } - if (emu_a.begin(picc, picc_memory, sizeof(picc_memory))) { - lcd.fillScreen(TFT_DARKGREEN); - lcd.setCursor(0, 16); - const auto& e_picc = emu_a.emulatePICC(); - M5.Log.printf("Emulation:%s %s ATQA:%04X SAK:%u\n", e_picc.typeAsString().c_str(), e_picc.uidAsString().c_str(), - e_picc.atqa, e_picc.sak); - lcd.printf("%s\n%s\nATQA:%04X SAK:%u", e_picc.typeAsString().c_str(), e_picc.uidAsString().c_str(), e_picc.atqa, - e_picc.sak); - } else { - lcd.fillScreen(TFT_RED); + if (emu_a.begin(picc, picc_memory, sizeof(picc_memory))) { + lcd.fillScreen(TFT_DARKGREEN); + lcd.setCursor(0, 16); + const auto& e_picc = emu_a.emulatePICC(); + M5.Log.printf("Emulation:%s %s ATQA:%04X SAK:%u\n", e_picc.typeAsString().c_str(), + e_picc.uidAsString().c_str(), e_picc.atqa, e_picc.sak); + lcd.printf("%s\n%s\nATQA:%04X SAK:%u", e_picc.typeAsString().c_str(), e_picc.uidAsString().c_str(), + e_picc.atqa, e_picc.sak); + } } lcd.fillRect(0, 0, 32, 16, color_table[0]); lcd.drawString(state_table[0], 0, 0); + lcd.endWrite(); } -/* - 17:31:54.797 > PICC:04C90EC2DA1C94 NTAG 213 144/180 -17:31:54.828 > Page :00 01 02 03 -17:31:54.832 > -------------------- -17:31:54.834 > [000/00]:04 C9 0E 4B -17:31:54.840 > [001/01]:C2 DA 1C 94 -17:31:54.840 > [002/02]:90 48 00 00 - - -17:34:34.767 > [000/00]:04 C9 0E 4B -17:34:34.767 > [001/01]:C2 DA 1C 94 -17:34:34.767 > [002/02]:18 A3 00 00 -*/ void loop() { M5.update(); diff --git a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp index 516bf57..4033dd6 100644 --- a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp +++ b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp @@ -241,6 +241,13 @@ void setup() M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } +/////////////////////////////////////// +// NRT 計算が正しいか確認 RFAL 比較 +// S3:PICC Hacker:NDEF で通すことを目標? +// PCD からくる? FRT とかはのうタイミングは? +// ISR での IRQ取得のトランザクションは? +// no_crc 除去? RFAL は? + void loop() { M5.update(); diff --git a/platformio.ini b/platformio.ini index baaa9d9..037592c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -3,7 +3,8 @@ ; For UnitTest and examples (Using M5UnitUnified) ;----------------------------------------------------------------------- [platformio] -;default_envs = UnitNFC_NFCA_Detect_Core_Arduino_latest, UnitNFC_NFCA_Dump_Core_Arduino_latest, UnitNFC_NFCA_ReadWrite_Core_Arduino_latest, UnitNFC_NFCA_ValueBlock_Core_Arduino_latest, UnitNFC_NFCA_NDEF_Core_Arduino_latest, UnitNFC_NFCF_Detect_Core_Arduino_latest, UnitNFC_NFCF_Dump_Core_Arduino_latest, UnitNFC_NFCF_NDEF_Core_Arduino_latest, UnitNFC_NFCF_Subtract_Core_Arduino_latest, UnitNFC_NFCF_ReadWriteMAC_Core_Arduino_latest, UnitNFC_NFCF_JapanTransportationICCard_Core_Arduino_latest, UnitNFC_NFCV_Detect_CardputerADV_Arduino_latest, UnitNFC_NFCV_Dump_CardputerADV_Arduino_latest, UnitNFC_NFCV_NDEF_Core_Arduino_latest +;default_envs = UnitNFC_NFCA_Detect_Core_Arduino_latest, UnitNFC_NFCA_Dump_Core_Arduino_latest, UnitNFC_NFCA_ReadWrite_Core_Arduino_latest, UnitNFC_NFCA_ValueBlock_Core_Arduino_latest, UnitNFC_NFCA_NDEF_Core_Arduino_latest, UnitNFC_NFCF_Detect_Core_Arduino_latest, UnitNFC_NFCF_Dump_Core_Arduino_latest, UnitNFC_NFCF_NDEF_Core_Arduino_latest, UnitNFC_NFCF_Subtract_Core_Arduino_latest, UnitNFC_NFCF_ReadWriteMAC_Core_Arduino_latest, UnitNFC_NFCF_JapanTransportationICCard_Core_Arduino_latest, UnitNFC_NFCV_Detect_CardputerADV_Arduino_latest, UnitNFC_NFCV_Dump_CardputerADV_Arduino_latest, UnitNFC_NFCV_NDEF_Core_Arduino_latest, UnitNFC_NFCB_Detect_Core_Arduino_latest, UnitNFC_NFCB_Dump_Core_Arduino_latest, CapHacker_NFCB_Detect_CardputerADV_Arduino_latest, CapHacker_NFCB_Dump_CardputerADV_Arduino_latest + [env] @@ -234,6 +235,28 @@ build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/NFCA/NDEF> build_flags = ${option_release.build_flags} -D USING_UNIT_NFC +[env:UnitNFC_NFCA_Emulation_Core_Arduino_latest] +extends=Core, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/NFCA/Emulation> +build_flags = ${option_release.build_flags} + -D USING_UNIT_NFC + + + +; NFC-B +[env:UnitNFC_NFCB_Detect_Core_Arduino_latest] +extends=Core, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/NFCB/Detect> +build_flags = ${option_release.build_flags} + -D USING_UNIT_NFC + +[env:UnitNFC_NFCB_Dump_Core_Arduino_latest] +extends=Core, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/NFCB/Dump> +build_flags = ${option_release.build_flags} + -D USING_UNIT_NFC + + ; NFC-F [env:UnitNFC_NFCF_Detect_Core_Arduino_latest] extends=Core, option_release, arduino_latest @@ -329,6 +352,14 @@ build_flags = ${option_release.build_flags} ${CardputerADV.build_flags} -D USING_HACKER_CAP +[env:CapHacker_NFCA_Emulation_CardputerADV_Arduino_latest] +extends=CardputerADV, option_release, arduino_latest +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/UnitUnified/NFCA/Emulation> +build_flags = ${option_release.build_flags} + ${CardputerADV.build_flags} + -D USING_HACKER_CAP + + ; NFC-B [env:CapHacker_NFCB_Detect_CardputerADV_Arduino_latest] extends=CardputerADV, option_release, arduino_latest diff --git a/src/nfc/layer/a/emulation_layer_a.cpp b/src/nfc/layer/a/emulation_layer_a.cpp index 7141cf4..1860429 100644 --- a/src/nfc/layer/a/emulation_layer_a.cpp +++ b/src/nfc/layer/a/emulation_layer_a.cpp @@ -31,6 +31,11 @@ bool EmulationLayerA::begin(const m5::nfc::a::PICC& picc, uint8_t* ptr, const ui return false; } + if (!(picc.isNTAG() || picc.type == Type::MIFARE_Ultralight)) { + M5_LIB_LOGE("Not support %u %s", picc.type, picc.typeAsString().c_str()); + return false; + } + _picc = picc; _memory = ptr; _memory_size = size; @@ -43,6 +48,8 @@ bool EmulationLayerA::begin(const m5::nfc::a::PICC& picc, uint8_t* ptr, const ui _state = _impl->start_emulation(_picc) ? State::Off : State::None; _prev = State::None; + + _expired_at = m5::utility::millis() + _expired_ms; return (_state != State::None); } @@ -58,28 +65,31 @@ bool EmulationLayerA::end() void EmulationLayerA::update() { auto save = _state; + // if (_state != _prev) { + // _expired_at = m5::utility::millis() + _expired_ms; // IRQ byGT ??? + // } switch (_state) { 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: @@ -119,7 +129,6 @@ EmulationLayerA::State EmulationLayerA::receive_callback(const uint8_t* rx, cons return State::Idle; } // m5::utility::log::dump(rx, rx_len, false); - M5_LIB_LOGE("cmd:%02X %u", rx[0], rx_len); State ret{State::Idle}; switch (static_cast(rx[0])) { @@ -127,6 +136,8 @@ EmulationLayerA::State EmulationLayerA::receive_callback(const uint8_t* rx, cons ret = (rx_len == 2 && rx[1] == 0x00) ? State::Halt : State::Idle; break; case Command::READ: // 16 bytes read + // M5_LIB_LOGE(" R:%u", rx[1]); + ret = (rx_len == 2) && _impl->transmit(_memory + _picc.unitSize() * rx[1], 16, 4) ? State::Active : State::Idle; break; @@ -156,6 +167,7 @@ EmulationLayerA::State EmulationLayerA::receive_callback(const uint8_t* rx, cons const uint32_t offset = 4 * rx[1]; if (offset + 4 <= _memory_size) { memcpy(_memory + offset, rx + 2, 4); + // ret = _impl->send_ack() ? State::Active : State::Idle; // Return ACK ret = _impl->transmit(&ACK_NIBBLE, 1, 1) ? State::Active : State::Idle; // Return ACK } } @@ -170,6 +182,7 @@ EmulationLayerA::State EmulationLayerA::receive_callback(const uint8_t* rx, cons break; default: + M5_LIB_LOGE("cmd:%02X %u", rx[0], rx_len); break; } // M5_LIB_LOGE(" --> %u", ret); diff --git a/src/nfc/layer/a/emulation_layer_a.hpp b/src/nfc/layer/a/emulation_layer_a.hpp index a747343..c7295f7 100644 --- a/src/nfc/layer/a/emulation_layer_a.hpp +++ b/src/nfc/layer/a/emulation_layer_a.hpp @@ -51,16 +51,25 @@ public: { return _picc; } + inline uint32_t expiredTime() const + { + return _expired_ms; + } + void setExpiredTime(const uint32_t ms) + { + _expired_ms = ms; + } bool begin(const m5::nfc::a::PICC& picc, uint8_t* ptr, const uint32_t size); bool end(); void update(); - State receive_callback(const uint8_t* rx, const uint32_t rx_len); + virtual State receive_callback(const uint8_t* rx, const uint32_t rx_len); protected: - bool load_config(); + void update_expired(); +private: void update_off(); void update_idle(); void update_ready(); @@ -73,7 +82,7 @@ protected: private: State _state{}, _prev{}; - uint32_t _expired_ms{10*1000}; + uint32_t _expired_ms{60 * 1000u}; unsigned int _expired_at{}; std::unique_ptr _impl; m5::nfc::a::PICC _picc{}; @@ -84,9 +93,6 @@ private: struct EmulationLayerA::Adapter { virtual ~Adapter() = default; - // virtual uint16_t max_fifo_depth() = 0; - - virtual bool load_config(const m5::nfc::a::PICC& picc) = 0; virtual bool start_emulation(const m5::nfc::a::PICC& picc) = 0; virtual bool stop_emulation() = 0; virtual bool transmit(const uint8_t* tx, const uint16_t tx_len, const uint32_t timeout_ms) = 0; diff --git a/src/nfc/layer/nfc_layer_a.cpp b/src/nfc/layer/nfc_layer_a.cpp index d2027cf..6749cf3 100644 --- a/src/nfc/layer/nfc_layer_a.cpp +++ b/src/nfc/layer/nfc_layer_a.cpp @@ -277,6 +277,7 @@ 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 @@ -981,12 +982,11 @@ bool NFCLayerA::dump_page_structure(const uint16_t maxPage) "Page :00 01 02 03\n" "--------------------"); + bool ret{true}; for (uint_fast8_t page = 0; page < maxPage; page += 4) { - if (!dump_page(page, maxPage)) { - return false; - } + ret &= dump_page(page, maxPage); } - return true; + return ret; } bool NFCLayerA::dump_page(const uint8_t page, uint16_t maxPage) diff --git a/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp b/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp index f4ec383..87aa2e2 100644 --- a/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp +++ b/src/nfc/layer/unit/emulation_layer_a_ST25R3916.cpp @@ -245,6 +245,8 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_off() _u.enable_interrupts(I_nfct32 | I_rxs32 | I_crc32 | I_err132 | I_osc32 | I_err232 | I_par32 | I_eon32 | I_eof32 | mode_irq); + _u.set_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx); + if (is_extra_field()) { return goto_idle(); } else { @@ -270,8 +272,9 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_idle() (void)get_irq(I_osc32); } + _u.set_bit_register8(REG_AUXILIARY_DEFINITION, no_crc_rx); + if (_layer.state() == EmulationLayerA::State::Active && !_wakeup) { - M5_LIB_LOGE(" >> Active to idle"); _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); } @@ -291,6 +294,9 @@ EmulationLayerA::State ListenerST25R3916ForA::goto_ready() return goto_off(); } + _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); @@ -364,7 +370,7 @@ EmulationLayerA::State ListenerST25R3916ForA::update_idle() } if (is_eof(irq32) && !_data_flag) { - M5_LIB_LOGE("OFF"); + //M5_LIB_LOGE("OFF"); return goto_off(); } if ((irq32 & I_rxe32) && _bitrate != Bitrate::Invalid) {