@@ -320,25 +320,27 @@ bool em4x05_read(em4x05_data_t *out, uint32_t timeout_ms) {
320320 return false;
321321 }
322322
323- /* Extract LWR (Last Word Read) from config - bits 19-16.
324- * In EM410x-compat mode the UID lives in the LWR block (often block 6).
325- * In native EM4x05 mode the UID is in block 15.
326- * Try LWR block first, fall back to block 15. */
323+ /* Extract LWR (Last Word Read) from config word bits 19-16.
324+ * This field tells us the highest block the tag will auto-transmit,
325+ * and the UID lives in block 1 for EM4305/EM UNIQUE mode, or block 15
326+ * for native EM4x05. Blocks 14-15 on EM4305 are lock fields.
327+ *
328+ * Strategy:
329+ * LWR=1 -> EM UNIQUE/PAXTON mode, UID in block 1
330+ * LWR>1 and <14 -> custom config, UID in LWR block
331+ * LWR=0 or >=14 -> native EM4x05, UID in block 15
332+ */
327333 uint8_t lwr = (out -> config >> 16 ) & 0xF ;
328- uint8_t uid_block = (lwr > 0 && lwr < 15 ) ? lwr : EM4X05_BLOCK_UID ;
334+ uint8_t uid_block ;
335+ if (lwr >= 1 && lwr < 14 ) {
336+ uid_block = lwr ; /* EM4305/EM UNIQUE: UID at LWR block */
337+ } else {
338+ uid_block = EM4X05_BLOCK_UID ; /* native EM4x05: UID at block 15 */
339+ }
329340
330341 if (!em4x05_read_block (uid_block , & out -> uid , block_timeout )) {
331- /* Try block 15 as fallback */
332- if (uid_block != EM4X05_BLOCK_UID ) {
333- if (!em4x05_read_block (EM4X05_BLOCK_UID , & out -> uid , block_timeout )) {
334- NRF_LOG_DEBUG ("em4x05: UID block read failed" );
335- return false;
336- }
337- uid_block = EM4X05_BLOCK_UID ;
338- } else {
339- NRF_LOG_DEBUG ("em4x05: block 15 read failed" );
340- return false;
341- }
342+ NRF_LOG_DEBUG ("em4x05: UID block %d read failed" , uid_block );
343+ return false;
342344 }
343345 out -> uid_block = uid_block ;
344346
0 commit comments