From 944e87343bb630c92d798ee5dc91fcb89e696773 Mon Sep 17 00:00:00 2001 From: GOB Date: Mon, 6 Apr 2026 19:48:03 +0900 Subject: [PATCH] Fixes examples: I2C NanoC6 branching, typos, and log messages --- .../UnitUnified/NFCA/Detect/main/Detect.cpp | 56 +++++-- examples/UnitUnified/NFCA/Dump/main/Dump.cpp | 54 ++++-- .../NFCA/Emulation/main/Emulation.cpp | 39 +++-- examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp | 49 ++++-- examples/UnitUnified/NFCA/README.md | 6 + .../NFCA/ReadWrite/main/ReadWrite.cpp | 49 ++++-- .../NFCA/ValueBlock/main/ValueBlock.cpp | 158 ++++++++++++++++-- .../UnitUnified/NFCB/Detect/main/Detect.cpp | 29 ++-- .../NFCB/JapanIDCard/JapanIDCard.ino | 2 +- .../NFCB/JapanIDCard/main/JapanIDCard.cpp | 34 ++-- .../UnitUnified/NFCF/Detect/main/Detect.cpp | 29 ++-- examples/UnitUnified/NFCF/Dump/main/Dump.cpp | 28 ++-- .../NFCF/Emulation/main/Emulation.cpp | 28 ++-- .../main/JapanTransportationICCard.cpp | 30 ++-- examples/UnitUnified/NFCF/NDEF/main/NDEF.cpp | 30 ++-- .../NFCF/ReadWriteMAC/main/ReadWriteMAC.cpp | 40 +++-- .../NFCF/Subtract/main/Subtract.cpp | 28 ++-- .../UnitUnified/NFCV/Detect/main/Detect.cpp | 29 ++-- examples/UnitUnified/NFCV/Dump/main/Dump.cpp | 28 ++-- examples/UnitUnified/NFCV/NDEF/main/NDEF.cpp | 31 ++-- 20 files changed, 565 insertions(+), 212 deletions(-) create mode 100644 examples/UnitUnified/NFCA/README.md diff --git a/examples/UnitUnified/NFCA/Detect/main/Detect.cpp b/examples/UnitUnified/NFCA/Detect/main/Detect.cpp index 1ea483b..4b3ba86 100644 --- a/examples/UnitUnified/NFCA/Detect/main/Detect.cpp +++ b/examples/UnitUnified/NFCA/Detect/main/Detect.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include // For NessoN1 #include // ************************************************************* @@ -54,17 +56,46 @@ m5::nfc::NFCLayerA nfc_a{unit}; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); + + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } #if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + // NessoN1: Arduino Wire (I2C_NUM_0) cannot be used for GROVE port. + // Wire is used by M5Unified In_I2C for internal devices. + // Reconfiguring Wire to GROVE pins breaks In_I2C. + // Solution: Use SoftwareI2C via M5HAL (bit-banging) for the GROVE port. + // NanoC6: Wire.begin() on GROVE pins conflicts with Ex_I2C on the same I2C_NUM_0. + // Solution: Use M5.Ex_I2C directly instead of Arduino Wire. + auto board = M5.getBoard(); + bool unit_ready{}; +#if defined(USING_M5DIAL_BUILTIN_WS1850S) + // M5Dial builtin WS1850S on In_I2C (G12/G11, shared with RTC8563) + M5_LOGI("Using M5.In_I2C for builtin WS1850S"); + unit_ready = Units.add(unit, M5.In_I2C) && Units.begin(); +#else + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + // NanoC6: Use M5.Ex_I2C (m5::I2C_Class, not Arduino Wire) + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } +#endif // USING_M5DIAL_BUILTIN_WS1850S + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -87,15 +118,12 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { - lcd.setRotation(1); - } lcd.setFont(&fonts::Font0); lcd.fillScreen(0); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); } void loop() @@ -106,7 +134,7 @@ void loop() std::vector piccs; if (nfc_a.detect(piccs)) { lcd.fillScreen(0); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); uint16_t idx{}; for (auto&& u : piccs) { M5.Speaker.tone(6000, 5); diff --git a/examples/UnitUnified/NFCA/Dump/main/Dump.cpp b/examples/UnitUnified/NFCA/Dump/main/Dump.cpp index 51613db..73e1b4c 100644 --- a/examples/UnitUnified/NFCA/Dump/main/Dump.cpp +++ b/examples/UnitUnified/NFCA/Dump/main/Dump.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include // For NessoN1 #include // ************************************************************* @@ -62,16 +64,37 @@ void setup() M5.begin(); M5.setTouchButtonHeightByRatio(100); -#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - if (!Units.add(unit, Wire) || !Units.begin()) { +#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) + auto board = M5.getBoard(); + bool unit_ready{}; +#if defined(USING_M5DIAL_BUILTIN_WS1850S) + // M5Dial builtin WS1850S on In_I2C (G12/G11, shared with RTC8563) + M5_LOGI("Using M5.In_I2C for builtin WS1850S"); + unit_ready = Units.add(unit, M5.In_I2C) && Units.begin(); +#else + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } +#endif // USING_M5DIAL_BUILTIN_WS1850S + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -94,15 +117,12 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { - lcd.setRotation(1); - } lcd.setFont(&fonts::Font0); - lcd.fillScreen(0); - lcd.setCursor(0, 0); + lcd.fillScreen(TFT_DARKGREEN); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click BtnA"); M5.Log.printf("Please put the PICC and click BtnA\n"); } @@ -113,19 +133,23 @@ void loop() Units.update(); if (M5.BtnA.wasClicked()) { - lcd.fillRect(0, lcd.fontHeight(), lcd.width(), lcd.height() - lcd.fontHeight()); + lcd.fillScreen(TFT_DARKGREEN); + lcd.setCursor(0, lcd.height() / 2); PICC picc{}; if (nfc_a.detect(picc)) { if (nfc_a.identify(picc) && nfc_a.reactivate(picc)) { M5.Speaker.tone(3000, 20); + lcd.printf("%s\n%s", picc.uidAsString().c_str(), picc.typeAsString().c_str()); M5.Log.printf("==== Dump %s %s %u/%u ====\n", picc.uidAsString().c_str(), picc.typeAsString().c_str(), picc.userAreaSize(), picc.totalSize()); nfc_a.dump(keyA); // Need key if MIFARE classic, Ignore key if not MIFARE classic nfc_a.deactivate(); } else { + lcd.printf("Failed to identify"); M5_LOGE("Failed to identify/activate %s", picc.uidAsString().c_str()); } } else { + lcd.printf("PICC NOT exists"); M5.Log.printf("PICC NOT exists\n"); } } diff --git a/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp b/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp index 7312ada..ad0b041 100644 --- a/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp +++ b/examples/UnitUnified/NFCA/Emulation/main/Emulation.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include // For NessoN1 #include // ************************************************************* @@ -157,11 +159,14 @@ constexpr const char* state_table[] = {"-", "O", "I", "R", "A", "H"}; void setup() { - delay(1500); - M5.begin(); M5.setTouchButtonHeightByRatio(100); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } + // Emulation settings auto cfg = unit.config(); cfg.emulation = true; @@ -169,14 +174,25 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -199,12 +215,9 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { - lcd.setRotation(1); - } lcd.setFont(&fonts::Font2); // diff --git a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp index e9f80e2..ed17c9c 100644 --- a/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp +++ b/examples/UnitUnified/NFCA/NDEF/main/NDEF.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include // For NessoN1 #include #include @@ -180,7 +182,7 @@ void write_ndef() */ if (picc.isMifareUltralight()) { if (!nfc_a.mifareUltralightChangeFormatToNDEF()) { - M5_LOGE("Failed to mifareUltralightChangeFormatToNTAG"); + M5_LOGE("Failed to mifareUltralightChangeFormatToNDEF"); lcd.fillScreen(TFT_RED); return; } @@ -219,7 +221,7 @@ void write_ndef() // URI record r[0].setURIPayload("m5stack.com/", URIProtocol::HTTPS); - // Text record with langage type + // Text record with language type const char* zh_data = "你好 M5Stack"; r[1].setTextPayload(zh_data, "zh"); const char* en_data = "Hello M5Stack"; @@ -257,16 +259,37 @@ void setup() M5.begin(); M5.setTouchButtonHeightByRatio(100); -#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - if (!Units.add(unit, Wire) || !Units.begin()) { +#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) + auto board = M5.getBoard(); + bool unit_ready{}; +#if defined(USING_M5DIAL_BUILTIN_WS1850S) + // M5Dial builtin WS1850S on In_I2C (G12/G11, shared with RTC8563) + M5_LOGI("Using M5.In_I2C for builtin WS1850S"); + unit_ready = Units.add(unit, M5.In_I2C) && Units.begin(); +#else + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } +#endif // USING_M5DIAL_BUILTIN_WS1850S + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -289,10 +312,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } @@ -331,7 +354,7 @@ void loop() M5_LOGE("Failed to identify/activate %s", picc.uidAsString().c_str()); } nfc_a.deactivate(); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } else { diff --git a/examples/UnitUnified/NFCA/README.md b/examples/UnitUnified/NFCA/README.md new file mode 100644 index 0000000..74b998f --- /dev/null +++ b/examples/UnitUnified/NFCA/README.md @@ -0,0 +1,6 @@ +# Examples shared with M5Unit-NFC + +Those examples shared with [M5Unit-NFC](https://github.com/m5stack/M5Unit-NFC) + +**Do not edit these files in the M5Unit-RFID repository.** +**Please apply the M5Unit-NFC side modifications via [script](../../../follow_nfc_examples.sh)** diff --git a/examples/UnitUnified/NFCA/ReadWrite/main/ReadWrite.cpp b/examples/UnitUnified/NFCA/ReadWrite/main/ReadWrite.cpp index bcbde49..a74a120 100644 --- a/examples/UnitUnified/NFCA/ReadWrite/main/ReadWrite.cpp +++ b/examples/UnitUnified/NFCA/ReadWrite/main/ReadWrite.cpp @@ -10,13 +10,15 @@ NFCLayerA read/write are performed only on the user area. - raed4/write4, raed16/write16 allows access to any position by setting safety == false, or use the unit-side API. - See also each header and Doxygen docuemnt. + read4/write4, read16/write16 allows access to any position by setting safety == false, or use the unit-side API. + See also each header and Doxygen document. */ #include #include #include #include +#include +#include // For NessoN1 #include // ************************************************************* @@ -645,16 +647,37 @@ void setup() M5.begin(); M5.setTouchButtonHeightByRatio(100); -#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - if (!Units.add(unit, Wire) || !Units.begin()) { +#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) + auto board = M5.getBoard(); + bool unit_ready{}; +#if defined(USING_M5DIAL_BUILTIN_WS1850S) + // M5Dial builtin WS1850S on In_I2C (G12/G11, shared with RTC8563) + M5_LOGI("Using M5.In_I2C for builtin WS1850S"); + unit_ready = Units.add(unit, M5.In_I2C) && Units.begin(); +#else + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } +#endif // USING_M5DIAL_BUILTIN_WS1850S + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -677,10 +700,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } @@ -731,7 +754,7 @@ void loop() } else { M5.Log.printf("PICC NOT exists\n"); } - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } diff --git a/examples/UnitUnified/NFCA/ValueBlock/main/ValueBlock.cpp b/examples/UnitUnified/NFCA/ValueBlock/main/ValueBlock.cpp index 20e1511..b1eea55 100644 --- a/examples/UnitUnified/NFCA/ValueBlock/main/ValueBlock.cpp +++ b/examples/UnitUnified/NFCA/ValueBlock/main/ValueBlock.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include // For NessoN1 #include // ************************************************************* @@ -231,7 +233,7 @@ void rechargeable_value_block(const uint8_t block, const Key& akey, const Key& b // Auth B if (!nfc_a.mifareClassicAuthenticateB(block, bkey)) { - M5_LOGE("Failed to AUTH A %u/%u", block, stb); + M5_LOGE("Failed to AUTH B %u/%u", block, stb); return; } @@ -307,6 +309,115 @@ void rechargeable_value_block(const uint8_t block, const Key& akey, const Key& b nfc_a.dump(block); } +// Scan all sectors and restore any value blocks to normal read/write blocks +// Also restores sector trailer access bits to default (001) +// Tries multiple key combinations: KeyA/KeyB may have been changed by previous operations +void restore_all_value_blocks(const Key& akey, const Key& bkey) +{ + auto& picc = nfc_a.activatedPICC(); + uint8_t st_block{}; + uint32_t restored{}; + constexpr Key zero_key = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Try to authenticate with multiple keys + // Note: After a failed auth, PICC goes to HALT state. Need reactivate before retry. + auto try_auth = [&](uint8_t stb) -> bool { + if (nfc_a.mifareClassicAuthenticateA(stb, akey)) { + M5_LOGI("Auth KeyA(default) OK for trailer %u", stb); + return true; + } + nfc_a.reactivate(); + if (nfc_a.mifareClassicAuthenticateA(stb, zero_key)) { + M5_LOGI("Auth KeyA(zero) OK for trailer %u", stb); + return true; + } + nfc_a.reactivate(); + if (nfc_a.mifareClassicAuthenticateB(stb, bkey)) { + M5_LOGI("Auth KeyB(default) OK for trailer %u", stb); + return true; + } + nfc_a.reactivate(); + if (nfc_a.mifareClassicAuthenticateB(stb, zero_key)) { + M5_LOGI("Auth KeyB(zero) OK for trailer %u", stb); + return true; + } + nfc_a.reactivate(); + return false; + }; + + // Pass 1: Restore sector trailer access bits first + // Some access conditions require KeyB for trailer writes + for (uint_fast16_t stb = 3; stb < picc.blocks; stb = get_sector_trailer_block(stb + 1)) { + if (!try_auth(stb)) { + M5_LOGW("Cannot auth sector trailer %u, skip", stb); + continue; + } + // Try with current auth (KeyA) + if (nfc_a.mifareClassicWriteAccessCondition(stb, 0x01 /*001*/, akey, bkey)) { + M5_LOGI("Restored trailer %u with KeyA", stb); + continue; + } + M5_LOGW("KeyA write failed for trailer %u, trying KeyB...", stb); + // KeyA write failed -> need KeyB auth for this trailer + nfc_a.reactivate(); + if (nfc_a.mifareClassicAuthenticateB(stb, bkey)) { + if (nfc_a.mifareClassicWriteAccessCondition(stb, 0x01, akey, bkey)) { + M5_LOGI("Restored trailer %u with KeyB(default)", stb); + continue; + } + } + nfc_a.reactivate(); + if (nfc_a.mifareClassicAuthenticateB(stb, zero_key)) { + if (nfc_a.mifareClassicWriteAccessCondition(stb, 0x01, akey, bkey)) { + M5_LOGI("Restored trailer %u with KeyB(zero)", stb); + continue; + } + } + M5_LOGE("Cannot restore trailer %u", stb); + nfc_a.reactivate(); + } + + // Pass 2: Find and restore value blocks + st_block = 0; + for (uint_fast16_t block = 0; block < picc.blocks; ++block) { + uint8_t stb = get_sector_trailer_block(block); + if (stb != st_block) { + st_block = stb; + if (!try_auth(stb)) { + block = stb; + continue; + } + } + if (block == stb || !picc.isUserBlock(block)) { + continue; + } + bool vb{}; + if (!nfc_a.mifareClassicIsValueBlock(vb, block)) { + continue; + } + if (!vb) { + continue; + } + + M5.Log.printf("Found value block [%u], restoring...\n", block); + + // Change to read/write block + if (!nfc_a.mifareClassicWriteAccessCondition(block, READ_WRITE_BLOCK, akey, bkey)) { + M5_LOGE("Failed to change access condition %u", block); + continue; + } + // Clear block data + uint8_t c[1]{}; + if (!nfc_a.write16(block, c, sizeof(c))) { + M5_LOGE("Failed to clear %u", block); + continue; + } + ++restored; + } + + M5.Log.printf("Restored %u value blocks\n", restored); +} + } // namespace void setup() @@ -314,16 +425,37 @@ void setup() M5.begin(); M5.setTouchButtonHeightByRatio(100); -#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); + // The screen shall be in landscape mode + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } - if (!Units.add(unit, Wire) || !Units.begin()) { +#if defined(USING_UNIT_NFC) || defined(USING_UNIT_RFID2) + auto board = M5.getBoard(); + bool unit_ready{}; +#if defined(USING_M5DIAL_BUILTIN_WS1850S) + // M5Dial builtin WS1850S on In_I2C (G12/G11, shared with RTC8563) + M5_LOGI("Using M5.In_I2C for builtin WS1850S"); + unit_ready = Units.add(unit, M5.In_I2C) && Units.begin(); +#else + // NessoN1: port_b (GROVE) uses SoftwareI2C (M5HAL Bus) which causes I2C register + // polling latency too high for MFRC522/WS1850S RF timing requirements. + // Use QWIIC (port_a) with Wire instead. (Requires QWIIC-GROVE conversion cable) + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } +#endif // USING_M5DIAL_BUILTIN_WS1850S + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -346,10 +478,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } @@ -373,11 +505,13 @@ void loop() lcd.fillScreen(TFT_BLUE); M5.Log.print("Non rechargeable\n"); non_rechargeable_value_block(picc.blocks - 2, keyA, keyB); + // nfc_a.dump(DEFAULT_KEY); } else if (held) { M5.Speaker.tone(4000, 30); lcd.fillScreen(TFT_YELLOW); M5.Log.print("Rechargeable\n"); rechargeable_value_block(picc.blocks - 2, keyA, keyB); + // restore_all_value_blocks(DEFAULT_KEY, DEFAULT_KEY); } M5.Log.printf("Please remove the PICC from the reader\n"); } else { @@ -390,7 +524,7 @@ void loop() } else { M5.Log.printf("PICC NOT exists\n"); } - lcd.setCursor(0, 0); + lcd.setCursor(0, lcd.height() / 2); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n"); } diff --git a/examples/UnitUnified/NFCB/Detect/main/Detect.cpp b/examples/UnitUnified/NFCB/Detect/main/Detect.cpp index 9f49a54..bb480e9 100644 --- a/examples/UnitUnified/NFCB/Detect/main/Detect.cpp +++ b/examples/UnitUnified/NFCB/Detect/main/Detect.cpp @@ -45,21 +45,30 @@ m5::nfc::NFCLayerB nfc_b{unit}; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); auto cfg = unit.config(); cfg.mode = NFC::B; unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -82,10 +91,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCB/JapanIDCard/JapanIDCard.ino b/examples/UnitUnified/NFCB/JapanIDCard/JapanIDCard.ino index 0418efb..7333f62 100644 --- a/examples/UnitUnified/NFCB/JapanIDCard/JapanIDCard.ino +++ b/examples/UnitUnified/NFCB/JapanIDCard/JapanIDCard.ino @@ -5,7 +5,7 @@ */ /* Example using M5UnitUnified for ST25R3916 - JapanIDCard exapmle + JapanIDCard example */ // ************************************************************* // Choose one define symbol to match the unit you are using diff --git a/examples/UnitUnified/NFCB/JapanIDCard/main/JapanIDCard.cpp b/examples/UnitUnified/NFCB/JapanIDCard/main/JapanIDCard.cpp index f433ba0..b0aa4a5 100644 --- a/examples/UnitUnified/NFCB/JapanIDCard/main/JapanIDCard.cpp +++ b/examples/UnitUnified/NFCB/JapanIDCard/main/JapanIDCard.cpp @@ -5,7 +5,7 @@ */ /* Example using M5UnitUnified for ST25R3916 - JapanIDCard exapmle + JapanIDCard example */ #include #include @@ -77,12 +77,12 @@ void dump() std::vector buf; if (!fs.readBinary(buf, 2, 1)) { - M5_LOGE("Failed to readBinay"); + M5_LOGE("Failed to readBinary"); return; } // buf[0] == size if (!fs.readBinary(buf, 0, buf[0])) { - M5_LOGE("Failed to readBinay"); + M5_LOGE("Failed to readBinary"); return; } m5::utility::log::dump(buf.data(), buf.size(), false); @@ -100,15 +100,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -131,10 +139,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCF/Detect/main/Detect.cpp b/examples/UnitUnified/NFCF/Detect/main/Detect.cpp index c727efe..86c4398 100644 --- a/examples/UnitUnified/NFCF/Detect/main/Detect.cpp +++ b/examples/UnitUnified/NFCF/Detect/main/Detect.cpp @@ -46,21 +46,30 @@ m5::nfc::NFCLayerF nfc_f{unit}; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); auto cfg = unit.config(); cfg.mode = NFC::F; unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -84,10 +93,10 @@ void setup() } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCF/Dump/main/Dump.cpp b/examples/UnitUnified/NFCF/Dump/main/Dump.cpp index c533276..ed2eaa9 100644 --- a/examples/UnitUnified/NFCF/Dump/main/Dump.cpp +++ b/examples/UnitUnified/NFCF/Dump/main/Dump.cpp @@ -53,15 +53,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -84,10 +92,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCF/Emulation/main/Emulation.cpp b/examples/UnitUnified/NFCF/Emulation/main/Emulation.cpp index 86a1092..217e4a9 100644 --- a/examples/UnitUnified/NFCF/Emulation/main/Emulation.cpp +++ b/examples/UnitUnified/NFCF/Emulation/main/Emulation.cpp @@ -107,15 +107,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -138,10 +146,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font2); diff --git a/examples/UnitUnified/NFCF/JapanTransportationICCard/main/JapanTransportationICCard.cpp b/examples/UnitUnified/NFCF/JapanTransportationICCard/main/JapanTransportationICCard.cpp index f0247ea..68b0710 100644 --- a/examples/UnitUnified/NFCF/JapanTransportationICCard/main/JapanTransportationICCard.cpp +++ b/examples/UnitUnified/NFCF/JapanTransportationICCard/main/JapanTransportationICCard.cpp @@ -134,7 +134,7 @@ void dump_jtic() break; } auto dt = buf_to_tm(buf + 6); - M5.Log.printf(" [%2u]:%4u/%02u/%02u %1u%1u:%1u%1u Enrty/Exit:%02X Gate:%03u-%03u/%04X Actuarial:%5u\n", // + M5.Log.printf(" [%2u]:%4u/%02u/%02u %1u%1u:%1u%1u Entry/Exit:%02X Gate:%03u-%03u/%04X Actuarial:%5u\n", // i, dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, // buf[8] >> 4, buf[8] & 0x0F, buf[9] >> 4, buf[9] & 0x0F, // BCD hour and min buf[0], buf[2], buf[3], // Station code if train @@ -200,15 +200,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -231,10 +239,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCF/NDEF/main/NDEF.cpp b/examples/UnitUnified/NFCF/NDEF/main/NDEF.cpp index 809b363..b1d8453 100644 --- a/examples/UnitUnified/NFCF/NDEF/main/NDEF.cpp +++ b/examples/UnitUnified/NFCF/NDEF/main/NDEF.cpp @@ -90,7 +90,7 @@ void write_ndef() // URI record r[0].setURIPayload("m5stack.com/", URIProtocol::HTTPS); - // Text record with langage type + // Text record with language type const char* en_data = "Hello M5Stack"; r[1].setTextPayload(en_data, "en"); const char* ja_data = "こんにちは M5Stack"; @@ -126,15 +126,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -157,10 +165,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCF/ReadWriteMAC/main/ReadWriteMAC.cpp b/examples/UnitUnified/NFCF/ReadWriteMAC/main/ReadWriteMAC.cpp index 64a8f3c..ce12d96 100644 --- a/examples/UnitUnified/NFCF/ReadWriteMAC/main/ReadWriteMAC.cpp +++ b/examples/UnitUnified/NFCF/ReadWriteMAC/main/ReadWriteMAC.cpp @@ -145,7 +145,7 @@ bool internal_auth() } // m5::utility::log::dump(rc, 16, false); - // Authenticattion + // Authentication return nfc_f.internalAuthenticate(ck, example_ckv, rc); } @@ -171,7 +171,7 @@ bool external_auth() // M5.Log.printf("==== CK:\n"); // m5::utility::log::dump(ck, 16, false); - // Authenticattion + // Authentication return nfc_f.externalAuthenticate(ck, example_ckv); } @@ -340,11 +340,11 @@ void access_example() lcd.fillScreen(0); } -bool first_issuance_procedue_lite_s(const PICC& picc, const uint8_t master_key[24], const uint16_t ckv) +bool first_issuance_procedure_lite_s(const PICC& picc, const uint8_t master_key[24], const uint16_t ckv) { uint8_t rbuf[16 * 4]{}; - M5.Log.printf("First issuance procedue...\n"); + M5.Log.printf("First issuance procedure...\n"); // 7.3.2 Write ID (No DFC) if (!nfc_f.write16(lite_s::ID, picc.idm, 8) || !nfc_f.read16(rbuf, lite_s::ID)) { @@ -488,15 +488,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -519,10 +527,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); @@ -551,8 +559,8 @@ void loop() if (clicked) { access_example(); } else { - if (!first_issuance_procedue_lite_s(picc, example_master_key, example_ckv)) { - M5_LOGE("Failed to first_issuance_procedue_lite_s"); + if (!first_issuance_procedure_lite_s(picc, example_master_key, example_ckv)) { + M5_LOGE("Failed to first_issuance_procedure_lite_s"); } } nfc_f.deactivate(); diff --git a/examples/UnitUnified/NFCF/Subtract/main/Subtract.cpp b/examples/UnitUnified/NFCF/Subtract/main/Subtract.cpp index e71bd7b..ea7f05d 100644 --- a/examples/UnitUnified/NFCF/Subtract/main/Subtract.cpp +++ b/examples/UnitUnified/NFCF/Subtract/main/Subtract.cpp @@ -116,15 +116,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -147,10 +155,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCV/Detect/main/Detect.cpp b/examples/UnitUnified/NFCV/Detect/main/Detect.cpp index ca642af..ba78f92 100644 --- a/examples/UnitUnified/NFCV/Detect/main/Detect.cpp +++ b/examples/UnitUnified/NFCV/Detect/main/Detect.cpp @@ -45,21 +45,30 @@ m5::nfc::NFCLayerV nfc_v{unit}; void setup() { M5.begin(); + M5.setTouchButtonHeightByRatio(100); auto cfg = unit.config(); cfg.mode = NFC::V; unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -82,10 +91,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCV/Dump/main/Dump.cpp b/examples/UnitUnified/NFCV/Dump/main/Dump.cpp index 6556846..3e120b1 100644 --- a/examples/UnitUnified/NFCV/Dump/main/Dump.cpp +++ b/examples/UnitUnified/NFCV/Dump/main/Dump.cpp @@ -53,15 +53,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -84,10 +92,10 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); - if (lcd.width() < lcd.height()) { + if (lcd.height() > lcd.width()) { lcd.setRotation(1); } lcd.setFont(&fonts::Font0); diff --git a/examples/UnitUnified/NFCV/NDEF/main/NDEF.cpp b/examples/UnitUnified/NFCV/NDEF/main/NDEF.cpp index cd0ecc2..02990cb 100644 --- a/examples/UnitUnified/NFCV/NDEF/main/NDEF.cpp +++ b/examples/UnitUnified/NFCV/NDEF/main/NDEF.cpp @@ -136,7 +136,7 @@ void write_ndef() // URI record r[0].setURIPayload("m5stack.com/", URIProtocol::HTTPS); - // Text record with langage type + // Text record with language type const char* zh_data = "你好 M5Stack"; r[1].setTextPayload(zh_data, "zh"); const char* en_data = "Hello M5Stack"; @@ -183,15 +183,23 @@ void setup() unit.config(cfg); #if defined(USING_UNIT_NFC) - auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); - auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); - 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); - - if (!Units.add(unit, Wire) || !Units.begin()) { + auto board = M5.getBoard(); + bool unit_ready{}; + // NessoN1: SoftwareI2C too slow for NFC RF timing -> use port_a (Wire) via else branch + if (board == m5::board_t::board_M5NanoC6) { + M5_LOGI("Using M5.Ex_I2C"); + unit_ready = Units.add(unit, M5.Ex_I2C) && Units.begin(); + } else { + auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); + auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); + 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); + unit_ready = Units.add(unit, Wire) && Units.begin(); + } + if (!unit_ready) { M5_LOGE("Failed to begin"); - lcd.clear(TFT_RED); + lcd.fillScreen(TFT_RED); while (true) { m5::utility::delay(10000); } @@ -214,9 +222,12 @@ void setup() } } #endif - M5_LOGI("M5UnitUnified has been begun"); + M5_LOGI("M5UnitUnified initialized"); M5_LOGI("%s", Units.debugInfo().c_str()); + if (lcd.height() > lcd.width()) { + lcd.setRotation(1); + } lcd.setCursor(0, 0); lcd.printf("Please put the PICC and click/hold BtnA"); M5.Log.printf("Please put the PICC and click/hold BtnA\n");