1212#include < M5UnitUnifiedRFID.h>
1313#include < M5Utility.h>
1414#include < wiring/m5_unit_unified_wiring.hpp>
15+ #include < algorithm>
1516#include < string>
1617#include < vector>
1718
@@ -81,19 +82,12 @@ std::string to_hex(const std::vector<uint8_t>& data)
8182// ! @brief Words the short write test replaces and then puts back
8283constexpr uint16_t WRITE_TEST_WORDS {2 };
8384/* !
84- @brief Words the long write test replaces and then puts back
85- @details The most a single Write command carries. The module programs the words into the tag
86- one at a time and waits out the tag's write time for each, so this is the longest a single
87- command legitimately takes. Monza 4QT holds exactly this much user memory
85+ @brief The most a single Write command carries
86+ @details The module programs the words into the tag one at a time and waits out the tag's
87+ write time for each, so a write of this many words is the longest a single command
88+ legitimately takes. Anything longer is split by writeBank into several
8889 */
8990constexpr uint16_t WRITE_TEST_MAX_WORDS {32 };
90- /* !
91- @brief Words the whole-bank write test replaces and then puts back
92- @details The full User bank of an Alien Higgs 9, 688 bits of it. More than a single Write
93- command carries, so writeBank splits it, which is the thing worth exercising here. A tag with
94- less user memory than this answers with a memory overrun and nothing is written
95- */
96- constexpr uint16_t WRITE_TEST_BANK_WORDS {43 };
9791
9892/* !
9993 Write a stretch of User memory, read it back and put the original contents back.
@@ -128,7 +122,9 @@ void write_roundtrip(const m5::uhf::Tag& detected, const uint16_t words)
128122 const unsigned long read_began = m5::utility::millis ();
129123 std::vector<uint8_t > original{};
130124 if (!uhf.readBank (original, m5::uhf::Bank::User, 0 , words)) {
131- M5_LOGE (" write %u words: this tag has no User memory to write to, or not that much of it" , words);
125+ // The caller sized this from what the tag holds, so a refusal here is not the bank being
126+ // too small; it is the read itself failing
127+ M5_LOGE (" write %u words: could not read what is there now, so nothing is written" , words);
132128 uhf.deselect ();
133129 return ;
134130 }
@@ -158,6 +154,7 @@ void write_roundtrip(const m5::uhf::Tag& detected, const uint16_t words)
158154 M5_LOGI (" write %2u words: read %lums, write %lums, read back %s" , words, read_took, took,
159155 readback == pattern ? " matches" : " MISMATCH" );
160156 lcd.printf (" %2u words %lums %s\n " , words, took, readback == pattern ? " ok" : " NG" );
157+ uhf.dump (m5::uhf::Bank::User, 0 , words);
161158
162159 // Put it back the way it was, and say so loudly if that does not work: the tag is left
163160 // holding the pattern in that case
@@ -170,6 +167,7 @@ void write_roundtrip(const m5::uhf::Tag& detected, const uint16_t words)
170167 if (uhf.readBank (restored, m5::uhf::Bank::User, 0 , words)) {
171168 M5_LOGI (" write %2u words: restored %s" , words, restored == original ? " matches" : " MISMATCH" );
172169 }
170+ uhf.dump (m5::uhf::Bank::User, 0 , words);
173171 uhf.deselect ();
174172}
175173} // namespace
@@ -193,15 +191,48 @@ void loop()
193191 if (M5 .BtnA .wasClicked ()) {
194192 lcd.fillScreen (TFT_DARKGREEN );
195193 lcd.setCursor (0 , 0 );
194+ m5::uhf::Tag detected{};
195+ if (!detect_one (detected)) {
196+ return ;
197+ }
198+ // How much user memory there is decides what is worth writing, and only the TID says
199+ // which chip this is
200+ if (!uhf.select (detected)) {
201+ M5_LOGE (" Failed to select the tag" );
202+ lcd.println (" select: failed" );
203+ return ;
204+ }
196205 m5::uhf::Tag tag{};
197- if (!detect_one (tag)) {
206+ const bool identified = uhf.identify (tag);
207+ uhf.deselect ();
208+ if (!identified) {
209+ M5_LOGE (" Failed to identify the tag" );
210+ lcd.println (" identify: failed" );
198211 return ;
199212 }
200- // Two words to see it work, then the most a single command carries, then more than that
201- // so writeBank has to split it across two
213+
214+ const uint16_t bank = static_cast <uint16_t >(tag.user_memory_bits / 16 );
215+ M5_LOGI (" %s: user memory %s" , tag.chipAsString ().c_str (),
216+ bank ? m5::utility::formatString (" %u words" , bank).c_str ()
217+ : (m5::uhf::pcUserMemoryIndicator (tag.pc ) ? " size not known" : " none" ));
218+ lcd.printf (" %s\n " , tag.chipAsString ().c_str ());
219+
220+ if (bank == 0 && !m5::uhf::pcUserMemoryIndicator (tag.pc )) {
221+ M5_LOGI (" Nothing to write to on this tag" );
222+ lcd.println (" no user memory" );
223+ return ;
224+ }
225+
226+ // Two words to see it work at all
202227 write_roundtrip (tag, WRITE_TEST_WORDS );
203- write_roundtrip (tag, WRITE_TEST_MAX_WORDS );
204- write_roundtrip (tag, WRITE_TEST_BANK_WORDS );
228+ // Then the most a single command carries, or the whole bank if that is smaller
229+ write_roundtrip (tag, bank ? std::min<uint16_t >(WRITE_TEST_MAX_WORDS , bank) : WRITE_TEST_MAX_WORDS );
230+ // Then the whole bank, which only tells us anything when it takes more than one command
231+ if (bank > WRITE_TEST_MAX_WORDS ) {
232+ write_roundtrip (tag, bank);
233+ } else if (bank) {
234+ M5_LOGI (" The whole bank fits in one command, so there is no split to exercise" );
235+ }
205236 }
206237}
207238
0 commit comments