feat(registers): ICODE feature-flags decoder (GET NXP SYSTEM INFO)

Add IcodeFeatureFlags (Register) for the 16-bit ICODE feature word
reported by GET NXP SYSTEM INFO (ICODE 3 Table 113; DNA/SLIX2 report a
subset). Read-only capability decoder — decode a captured word to see
what a tag supports. Fields mirror the existing _FEATURE_* constants
one-to-one (asserted in a test). 3 new tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-14 09:01:52 -07:00
parent e795b5bb1d
commit f9e56e32ef
3 changed files with 54 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ from pm3py.sim import (
NtagI2CConfig, NtagI2CSession, NtagI2CPtI2C, NT3H2111, NT3H2211,
Ntag5StatusReg, Ntag5ConfigReg, Ntag5LinkTag,
NxpKeyPrivileges, IcodeDnaTag,
IcodeFeatureFlags,
)
@@ -467,3 +468,26 @@ class TestNxpKeyPrivileges:
text = repr(NxpKeyPrivileges.build(read=True, destroy=True))
assert "NXP key privileges" in text
assert "read" in text and "destroy" in text
class TestIcodeFeatureFlags:
def test_bits_match_module_constants(self):
import pm3py.transponders.hf.iso15693.nxp.icode3 as ic3
# every declared field must line up with the _FEATURE_* constant of the same name
for name, bf in IcodeFeatureFlags.fields():
const = getattr(ic3, f"_FEATURE_{name.upper()}")
assert (1 << bf.lo) == const, name
def test_decode(self):
# um_pp(0) + counter(1) + originality_sig(8) + high_data_rates(15)
w = (1 << 0) | (1 << 1) | (1 << 8) | (1 << 15)
f = IcodeFeatureFlags(w)
assert f.um_pp is True and f.counter is True
assert f.originality_sig is True and f.high_data_rates is True
assert f.privacy is False
assert int(f) == w
def test_repr(self):
text = repr(IcodeFeatureFlags(0x0001))
assert "ICODE feature flags" in text
assert "um_pp" in text