mirror of
https://github.com/m5stack/M5Unit-NFC.git
synced 2026-05-20 11:48:34 -07:00
Move the processing to the layer side(NFCA), Fixes ReadWrite example
This commit is contained in:
@@ -268,7 +268,7 @@ void loop()
|
||||
if (clicked) {
|
||||
M5.Speaker.tone(2000, 30);
|
||||
lcd.fillScreen(TFT_BLUE);
|
||||
nfc_a.dump();
|
||||
// nfc_a.dump();
|
||||
read_ndef();
|
||||
} else if (held) {
|
||||
M5.Speaker.tone(4000, 30);
|
||||
|
||||
@@ -89,7 +89,7 @@ bool read_write(const uint8_t sblock, const char* msg, const Key& key)
|
||||
uint16_t rx_len = sizeof(buf);
|
||||
|
||||
// Write
|
||||
M5.Log.printf("================================ WRITE\n");
|
||||
M5.Log.printf("================================ WRITE %u len:%zu\n", sblock, sizeof(buf));
|
||||
if (nfc_a.write(sblock, (const uint8_t*)msg, len, key)) {
|
||||
lcd.fillScreen(TFT_ORANGE);
|
||||
nfc_a.dump();
|
||||
@@ -98,7 +98,10 @@ bool read_write(const uint8_t sblock, const char* msg, const Key& key)
|
||||
if (nfc_a.read(buf, rx_len, sblock, key)) {
|
||||
lcd.fillScreen(TFT_BLUE);
|
||||
M5.Log.printf("================================ VERIFY:%s\n", memcmp(buf, msg, len) == 0 ? "OK" : "NG");
|
||||
m5::utility::log::dump(buf, rx_len, false);
|
||||
if (memcmp(buf, msg, len)) {
|
||||
m5::utility::log::dump(buf, rx_len, false);
|
||||
M5_LOGE("VERIFY NG!!");
|
||||
}
|
||||
|
||||
// Clear
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@@ -162,7 +165,7 @@ void read_write_sector_structure(const uint8_t block, const Key& key)
|
||||
nfc_a.dump(block);
|
||||
}
|
||||
|
||||
// Using read4,16/write4 for Ultralight,NTAG
|
||||
// Using read4,write4 for Ultralight,NTAG
|
||||
void read_write_page_structure(const PICC& picc, const uint8_t page)
|
||||
{
|
||||
constexpr char msg[] = "M5";
|
||||
@@ -181,21 +184,19 @@ void read_write_page_structure(const PICC& picc, const uint8_t page)
|
||||
nfc_a.dump(aligned_page);
|
||||
|
||||
// Read
|
||||
uint8_t rbuf[16]{};
|
||||
if (picc.isNTAG()) {
|
||||
if (!nfc_a.read4(rbuf, page)) {
|
||||
M5_LOGE("Failed to read");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!nfc_a.read16(rbuf, aligned_page)) {
|
||||
M5_LOGE("Failed to read");
|
||||
return;
|
||||
}
|
||||
uint8_t rbuf[4]{};
|
||||
if (!nfc_a.read4(rbuf, page)) {
|
||||
M5_LOGE("Failed to read");
|
||||
return;
|
||||
}
|
||||
|
||||
bool verify = std::memcmp(rbuf, (const uint8_t*)msg, sizeof(msg)) == 0;
|
||||
M5.Log.printf("Verify %s\n", verify ? "OK" : "NG");
|
||||
M5.Log.printf("Verify %u %s\n", picc.isNTAG(), verify ? "OK" : "NG");
|
||||
if (!verify) {
|
||||
M5_LOGE("VERIFY NG!!");
|
||||
m5::utility::log::dump(msg, sizeof(msg), false);
|
||||
m5::utility::log::dump(rbuf, sizeof(rbuf), false);
|
||||
}
|
||||
|
||||
// Clear
|
||||
M5.Log.printf("Clear\n");
|
||||
@@ -285,7 +286,8 @@ void loop()
|
||||
M5.Speaker.tone(2000, 30);
|
||||
// Need key if MIFARE classic, Ignore key if not MIFARE classic
|
||||
read_all_user_area(keyA);
|
||||
auto ret = read_write(0, picc.userAreaSize() >= 120 ? long_msg : short_msg, keyA);
|
||||
auto ret =
|
||||
read_write(picc.firstUserBlock(), picc.userAreaSize() >= 120 ? long_msg : short_msg, keyA);
|
||||
lcd.fillScreen(ret ? 0 : TFT_RED);
|
||||
} else if (held) {
|
||||
M5.Speaker.tone(4000, 30);
|
||||
|
||||
@@ -297,7 +297,7 @@ bool NFCLayerA::read4(uint8_t rx[4], const uint8_t addr)
|
||||
|
||||
uint16_t rx_len{4};
|
||||
if (_activePICC.canFastRead()) {
|
||||
return _impl->ntag_read_page(rx, rx_len, addr, addr);
|
||||
return ntag_read_page(rx, rx_len, addr, addr);
|
||||
}
|
||||
uint8_t tmp[16]{};
|
||||
if (_impl->nfca_read_block(tmp, addr & ~0x03)) {
|
||||
@@ -311,7 +311,7 @@ bool NFCLayerA::read16(uint8_t rx[16], const uint8_t addr)
|
||||
{
|
||||
uint16_t rx_len{16};
|
||||
return rx && _activePICC.valid() &&
|
||||
(_activePICC.canFastRead() ? (_impl->ntag_read_page(rx, rx_len, addr, addr + 3) && rx_len == 16)
|
||||
(_activePICC.canFastRead() ? (ntag_read_page(rx, rx_len, addr, addr + 3) && rx_len == 16)
|
||||
: _impl->nfca_read_block(rx, addr));
|
||||
}
|
||||
|
||||
@@ -331,10 +331,9 @@ bool NFCLayerA::read_using_fast(uint8_t* rx, uint16_t& rx_len, const uint8_t add
|
||||
|
||||
const uint16_t last = get_last_user_block(t);
|
||||
uint16_t need_page = ((rx_len + 3) >> 2);
|
||||
// uint16_t from = std::min<uint16_t>(last, std::max<uint16_t>(addr, get_first_user_block(t)));
|
||||
uint16_t from = addr;
|
||||
uint16_t to = std::min<uint16_t>(from + need_page - 1, last);
|
||||
uint16_t pages = to - from + 1;
|
||||
uint16_t from = addr;
|
||||
uint16_t to = std::min<uint16_t>(from + need_page - 1, last);
|
||||
uint16_t pages = to - from + 1;
|
||||
|
||||
uint16_t read_size = pages << 2; // 4 byte unit
|
||||
if (read_size > rx_len) {
|
||||
@@ -360,7 +359,7 @@ bool NFCLayerA::read_using_fast(uint8_t* rx, uint16_t& rx_len, const uint8_t add
|
||||
|
||||
M5_LIB_LOGD(" READ:%u-%u %u %u/%u", spage, epage, len, actual, pages);
|
||||
|
||||
if (!_impl->ntag_read_page(rx + rx_len, len, spage, epage) || len != (ps << 2)) {
|
||||
if (!ntag_read_page(rx + rx_len, len, spage, epage) || len != (ps << 2)) {
|
||||
M5_LIB_LOGD("Failed to read %u-%u", spage, epage);
|
||||
return false;
|
||||
}
|
||||
@@ -440,7 +439,7 @@ bool NFCLayerA::write4(const uint8_t addr, const uint8_t* tx, const uint16_t tx_
|
||||
|
||||
uint8_t buf[4]{};
|
||||
memcpy(buf, tx, std::min<uint16_t>(4, tx_len));
|
||||
return _impl->nfca_write_page(addr, buf);
|
||||
return ntag_write_page(addr, buf);
|
||||
}
|
||||
|
||||
bool NFCLayerA::write16(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len, const bool safety)
|
||||
@@ -460,7 +459,7 @@ bool NFCLayerA::write16(const uint8_t addr, const uint8_t* tx, const uint16_t tx
|
||||
return false;
|
||||
}
|
||||
for (uint_fast8_t i = 0; i < 4; ++i) {
|
||||
if (!_impl->nfca_write_page(addr + i, buf + i * 4)) {
|
||||
if (!ntag_write_page(addr + i, buf + i * 4)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -574,15 +573,6 @@ bool NFCLayerA::write_using_write16(const uint8_t addr, const uint8_t* tx, const
|
||||
return written == tx_len;
|
||||
}
|
||||
|
||||
bool NFCLayerA::write(const uint8_t saddr, const uint8_t* tx, const uint16_t tx_len)
|
||||
{
|
||||
if (!tx || !tx_len || !_activePICC.valid()) {
|
||||
return false;
|
||||
}
|
||||
return _activePICC.supportsNFC() ? write_using_write4(saddr, tx, tx_len)
|
||||
: write_using_write16(saddr, tx, tx_len, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
bool NFCLayerA::dump(const Key& mkey)
|
||||
{
|
||||
if (_activePICC.valid()) {
|
||||
@@ -1087,6 +1077,7 @@ bool NFCLayerA::mifare_classic_value_block(const m5::nfc::a::Command cmd, const
|
||||
return _impl->mifare_classic_value_block(cmd, block, arg);
|
||||
}
|
||||
|
||||
// for ndef
|
||||
bool NFCLayerA::read(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr)
|
||||
{
|
||||
if (!rx || !rx_len || !_activePICC.valid()) {
|
||||
@@ -1096,6 +1087,17 @@ bool NFCLayerA::read(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr)
|
||||
: read_using_read16(rx, rx_len, saddr, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
// for NDEF
|
||||
bool NFCLayerA::write(const uint8_t saddr, const uint8_t* tx, const uint16_t tx_len)
|
||||
{
|
||||
if (!tx || !tx_len || !_activePICC.valid()) {
|
||||
return false;
|
||||
}
|
||||
return _activePICC.supportsNFC() ? write_using_write4(saddr, tx, tx_len)
|
||||
: write_using_write16(saddr, tx, tx_len, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
//
|
||||
bool NFCLayerA::mifare_ultralightC_authenticate1(uint8_t ek[8])
|
||||
{
|
||||
uint8_t cmd[2] = {m5::stl::to_underlying(Command::AUTHENTICATE_1), 0x00};
|
||||
@@ -1255,5 +1257,42 @@ bool NFCLayerA::mifare_get_version_L4(uint8_t* ver, uint16_t& ver_len)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NFCLayerA::ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage)
|
||||
{
|
||||
if (!rx || !rx_len || spage > epage || !_activePICC.valid()) {
|
||||
return false;
|
||||
}
|
||||
uint8_t cmd[3] = {m5::stl::to_underlying(Command::FAST_READ), spage, epage};
|
||||
const uint8_t pages = epage - spage + 1;
|
||||
uint16_t timeout = (pages == 1) ? TIMEOUT_FAST_READ
|
||||
: (pages < 4) ? TIMEOUT_FAST_READ_4PAGE
|
||||
: (pages < 12) ? TIMEOUT_FAST_READ_12PAGE
|
||||
: (pages < 32) ? TIMEOUT_FAST_READ_32PAGE
|
||||
: TIMEOUT_FAST_READ_32PAGE * 2;
|
||||
|
||||
if (!_impl->transceive(rx, rx_len, cmd, sizeof(cmd), timeout)) {
|
||||
M5_LIB_LOGD("Failed to transceive");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NFCLayerA::ntag_write_page(const uint8_t page, const uint8_t tx[4])
|
||||
{
|
||||
if (!tx || !_activePICC.valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// M5_LIB_LOGD("WRITE_PAGE:%u", page);
|
||||
// m5::utility::log::dump(tx, 4, false);
|
||||
uint8_t cmd[6]{m5::stl::to_underlying(m5::nfc::a::Command::WRITE_PAGE), page};
|
||||
std::memcpy(cmd + 2, tx, 4);
|
||||
|
||||
uint8_t rx[1]{};
|
||||
uint16_t rx_len{1};
|
||||
return _impl->transceive(rx, rx_len, cmd, sizeof(cmd), TIMEOUT_WRITE1);
|
||||
}
|
||||
|
||||
} // namespace nfc
|
||||
} // namespace m5
|
||||
|
||||
@@ -501,6 +501,9 @@ protected:
|
||||
bool mifare_ultralightC_authenticate1(uint8_t ek[8]);
|
||||
bool mifare_ultralightC_authenticate2(uint8_t rx_ek[8], const uint8_t tx_ek[16]);
|
||||
|
||||
bool ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage);
|
||||
bool ntag_write_page(const uint8_t page, const uint8_t tx[4]); // NTAG,UL,ULC
|
||||
|
||||
bool dump_sector_structure(const m5::nfc::a::PICC& picc, const m5::nfc::a::mifare::classic::Key& key);
|
||||
bool dump_sector(const uint8_t sector);
|
||||
bool dump_page_structure(const uint16_t maxPage);
|
||||
@@ -527,27 +530,21 @@ struct NFCLayerA::Adapter {
|
||||
|
||||
virtual bool transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
|
||||
const uint32_t timeout_ms) = 0;
|
||||
// virtual bool mifare_transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
|
||||
// const uint32_t timeout_ms) = 0;
|
||||
|
||||
virtual bool request(uint16_t& atqa) = 0;
|
||||
virtual bool wakeup(uint16_t& atqa) = 0;
|
||||
|
||||
virtual bool select(m5::nfc::a::PICC& picc) = 0;
|
||||
virtual bool activate(const m5::nfc::a::PICC& picc) = 0;
|
||||
virtual bool hlt() = 0;
|
||||
|
||||
virtual bool nfca_read_block(uint8_t rx[16], const uint8_t addr) = 0; // READ
|
||||
virtual bool nfca_write_block(const uint8_t addr, const uint8_t tx[16]) = 0; // WRITE_BLOCK
|
||||
virtual bool nfca_write_page(const uint8_t addr, const uint8_t tx[4]) = 0; // WRITE_PAGE
|
||||
virtual bool hlt() = 0;
|
||||
|
||||
// Due to the chip-side cryptographic mechanism, the following shall be treated as an independent API
|
||||
virtual bool nfca_read_block(uint8_t rx[16], const uint8_t addr) = 0;
|
||||
virtual bool nfca_write_block(const uint8_t addr, const uint8_t tx[16]) = 0;
|
||||
virtual bool mifare_classic_authenticate(const bool auth_a, const m5::nfc::a::PICC& picc, const uint8_t block,
|
||||
const m5::nfc::a::mifare::classic::Key& key) = 0;
|
||||
virtual bool mifare_classic_value_block(const m5::nfc::a::Command cmd, const uint8_t block,
|
||||
const uint32_t arg = 0) = 0;
|
||||
|
||||
virtual bool ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage,
|
||||
const uint8_t epage) = 0; // FAST_READ
|
||||
};
|
||||
///@endcond
|
||||
|
||||
|
||||
@@ -47,16 +47,12 @@ struct PollerST25R3916ForA final : NFCLayerA::Adapter {
|
||||
|
||||
virtual bool nfca_read_block(uint8_t rx[16], const uint8_t addr) override; // READ
|
||||
virtual bool nfca_write_block(const uint8_t addr, const uint8_t tx[16]) override; // WRITE_BLOCK
|
||||
virtual bool nfca_write_page(const uint8_t addr, const uint8_t tx[4]) override; // WRITE_PAGE
|
||||
|
||||
virtual bool mifare_classic_authenticate(const bool auth_a, const m5::nfc::a::PICC& picc, const uint8_t block,
|
||||
const m5::nfc::a::mifare::classic::Key& key) override;
|
||||
virtual bool mifare_classic_value_block(const m5::nfc::a::Command cmd, const uint8_t block,
|
||||
const uint32_t arg = 0) override;
|
||||
|
||||
virtual bool ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage,
|
||||
const uint8_t epage) override; // FAST_READ
|
||||
|
||||
UnitST25R3916& _u;
|
||||
};
|
||||
|
||||
@@ -111,11 +107,6 @@ bool PollerST25R3916ForA::nfca_write_block(const uint8_t addr, const uint8_t tx[
|
||||
return _u.nfcaWriteBlock(addr, tx);
|
||||
}
|
||||
|
||||
bool PollerST25R3916ForA::nfca_write_page(const uint8_t addr, const uint8_t tx[4])
|
||||
{
|
||||
return _u.nfcaWritePage(addr, tx);
|
||||
}
|
||||
|
||||
bool PollerST25R3916ForA::mifare_classic_authenticate(const bool auth_a, const PICC& picc, const uint8_t block,
|
||||
const Key& key)
|
||||
{
|
||||
@@ -128,11 +119,6 @@ bool PollerST25R3916ForA::mifare_classic_value_block(const m5::nfc::a::Command c
|
||||
return _u.mifareClassicValueBlock(cmd, block, arg);
|
||||
}
|
||||
|
||||
bool PollerST25R3916ForA::ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage)
|
||||
{
|
||||
return _u.ntagReadPage(rx, rx_len, spage, epage);
|
||||
}
|
||||
|
||||
//
|
||||
namespace {
|
||||
std::unique_ptr<NFCLayerA::Adapter> make_st25r3916_adapter(UnitST25R3916& u)
|
||||
|
||||
@@ -1799,20 +1799,11 @@ public:
|
||||
@pre The block must be authenticated if MIFARE classic
|
||||
*/
|
||||
bool nfcaWriteBlock(const uint8_t block, const uint8_t tx[16]);
|
||||
/*!
|
||||
@brief Write the 1 page (4 bytes)
|
||||
@param tx Send buffer (at least 4 bytes)
|
||||
@return True if successful
|
||||
@pre The block must be authenticated if MIFARE classic
|
||||
*/
|
||||
bool nfcaWritePage(const uint8_t page, const uint8_t tx[4]);
|
||||
|
||||
/*!
|
||||
@brief Hlt for PICC
|
||||
@return True if successful
|
||||
*/
|
||||
bool nfcaHlt();
|
||||
|
||||
///@}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
@@ -1854,20 +1845,6 @@ public:
|
||||
bool mifareClassicValueBlock(const m5::nfc::a::Command cmd, const uint8_t block, const uint32_t arg = 0);
|
||||
///@}
|
||||
|
||||
///@name NTAG
|
||||
///@{
|
||||
/*!
|
||||
@brief Read between specified pages
|
||||
@param rx Receiver buffer
|
||||
@param[in/out] rx_len in:Size of receive buffer out:actual read size
|
||||
@param spage Start reading page
|
||||
@param epage End reading page
|
||||
@return True if successful
|
||||
@warning Only PICC with the FAST_READ command
|
||||
*/
|
||||
bool ntagReadPage(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage);
|
||||
///@}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
///@name NFC-B
|
||||
///@{
|
||||
|
||||
@@ -218,41 +218,7 @@ bool UnitST25R3916::configure_emulation_a()
|
||||
uint32_t UnitST25R3916::nfcaTransceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
|
||||
const uint32_t timeout_ms)
|
||||
{
|
||||
#if 0
|
||||
CHECK_MODE();
|
||||
|
||||
const auto rx_len_org = rx_len;
|
||||
rx_len = 0;
|
||||
if (!rx || !rx_len_org || !tx || !tx_len) {
|
||||
return false;
|
||||
}
|
||||
// m5::utility::log::dump(tx, tx_len, 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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wait_for_FIFO(timeout_ms, rx_len_org)) {
|
||||
M5_LIB_LOGD("Timeout");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t actual{};
|
||||
auto bb = readFIFO(actual, rx, rx_len_org);
|
||||
if (bb) {
|
||||
M5_LIB_LOGV("readFIFO %u/%u %u/%u %02X", actual, rx_len_org, bb >> 16, bb & 0xFFFF, rx[0]);
|
||||
rx_len = actual;
|
||||
return bb;
|
||||
}
|
||||
M5_LIB_LOGD("Failed to readFIFO %u/%u", actual, rx_len_org);
|
||||
return false;
|
||||
#else
|
||||
return nfcaTransmit(tx, tx_len, timeout_ms) && nfcaReceive(rx, rx_len, timeout_ms);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UnitST25R3916::nfcaTransmit(const uint8_t* tx, const uint16_t tx_len, const uint32_t timeout_ms)
|
||||
@@ -619,29 +585,6 @@ bool UnitST25R3916::nfcaWriteBlock(const uint8_t addr, const uint8_t tx[16])
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnitST25R3916::nfcaWritePage(const uint8_t page, const uint8_t tx[4])
|
||||
{
|
||||
CHECK_MODE();
|
||||
|
||||
if (!tx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// M5_LIB_LOGD("WRITE_PAGE:%u", page);
|
||||
// m5::utility::log::dump(tx, 4, false);
|
||||
|
||||
uint8_t cmd[6]{m5::stl::to_underlying(m5::nfc::a::Command::WRITE_PAGE), page};
|
||||
std::memcpy(cmd + 2, tx, 4);
|
||||
|
||||
uint8_t rx[2]{};
|
||||
uint16_t rx_len{2};
|
||||
if (nfcaTransceive(rx, rx_len, cmd, sizeof(cmd), TIMEOUT_WRITE2)) {
|
||||
return true;
|
||||
}
|
||||
M5_LIB_LOGD("Failed to write page");
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------- For MIFARE classic
|
||||
bool UnitST25R3916::mifare_transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
|
||||
const uint32_t timeout_ms)
|
||||
@@ -896,29 +839,5 @@ bool UnitST25R3916::mifareClassicValueBlock(const m5::nfc::a::Command cmd, const
|
||||
return !wait_for_FIFO(TIMEOUT_VALUE_BLOCK); // Consider the timeout a success
|
||||
}
|
||||
|
||||
// -------------------------------- For NTAG
|
||||
bool UnitST25R3916::ntagReadPage(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage)
|
||||
{
|
||||
CHECK_MODE();
|
||||
|
||||
if (spage > epage) {
|
||||
return false;
|
||||
}
|
||||
uint8_t cmd[3] = {m5::stl::to_underlying(Command::FAST_READ), spage, epage};
|
||||
|
||||
const uint8_t pages = epage - spage + 1;
|
||||
uint16_t timeout = (pages == 1) ? TIMEOUT_FAST_READ
|
||||
: (pages < 4) ? TIMEOUT_FAST_READ_4PAGE
|
||||
: (pages < 12) ? TIMEOUT_FAST_READ_12PAGE
|
||||
: (pages < 32) ? TIMEOUT_FAST_READ_32PAGE
|
||||
: TIMEOUT_FAST_READ_32PAGE * 2;
|
||||
|
||||
if (!nfcaTransceive(rx, rx_len, cmd, sizeof(cmd), timeout)) {
|
||||
M5_LIB_LOGD("Failed to transceive");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace unit
|
||||
} // namespace m5
|
||||
|
||||
Reference in New Issue
Block a user