6.1 KiB
ICODE SLIX2 Command Audit
Date: 2026-03-17 Source: SL2S2602 datasheet Rev 4.2, AN11809 Rev 1.2, SL2S2002 datasheet Rev 3.4
Status
Commands marked OK are implemented in firmware native handler or response table. Commands marked MISSING need implementation in the Python transponder model + table compiler.
Standard ISO 15693 (firmware native handler)
| Cmd | Name | Status |
|---|---|---|
| 0x01 | INVENTORY | OK |
| 0x02 | STAY QUIET | OK |
| 0x20 | READ SINGLE BLOCK | OK (with lock_mode access control) |
| 0x21 | WRITE SINGLE BLOCK | OK (with lock_mode access control) |
| 0x22 | LOCK BLOCK | OK (firmware native) |
| 0x23 | READ MULTIPLE BLOCKS | OK |
| 0x25 | SELECT | OK |
| 0x26 | RESET TO READY | OK |
| 0x27 | WRITE AFI | OK (firmware native) |
| 0x28 | LOCK AFI | OK (firmware native) |
| 0x29 | WRITE DSFID | OK (firmware native) |
| 0x2A | LOCK DSFID | OK (firmware native) |
| 0x2B | GET SYSTEM INFO | OK |
| 0x2C | GET MULTIPLE BLOCK SECURITY | OK |
NXP Custom Commands (table entries)
| Code | Name | Status | Priority | Notes |
|---|---|---|---|---|
| 0xA0 | INVENTORY READ | OK | - | Like inventory but returns data blocks |
| 0xA1 | FAST INVENTORY READ | OK | - | Same as A0 at double data rate |
| 0xA2 | SET EAS | OK | - | Enables EAS mode (password protected) |
| 0xA3 | RESET EAS | OK | - | Disables EAS mode |
| 0xA4 | LOCK EAS | OK | - | Permanently locks EAS state |
| 0xA5 | EAS ALARM | OK | - | Returns 256-bit EAS sequence |
| 0xA6 | PASSWORD PROTECT EAS/AFI | OK | - | Enables password protection for EAS/AFI |
| 0xA7 | WRITE EAS ID | OK | - | Writes 16-bit EAS identifier |
| 0xAB | GET NXP SYSTEM INFO | OK | - | Returns PP, PP conditions, lock bits, feature flags |
| 0xB2 | GET RANDOM NUMBER | OK | - | Firmware native handler + Python model |
| 0xB3 | SET PASSWORD | OK | - | XOR password with GET_RANDOM, firmware + table entries |
| 0xB4 | WRITE PASSWORD | OK | - | Changes password value (requires prior SET PASSWORD) |
| 0xB5 | LOCK PASSWORD | OK | - | Permanently locks a password |
| 0xB6 | PROTECT PAGE | OK | - | Sets protection pointer + access conditions (requires write auth) |
| 0xB7 | LOCK PAGE PROTECTION | OK | - | Permanently locks protection config |
| 0xB9 | DESTROY | OK | - | Irreversibly kills tag (XOR password) |
| 0xBA | ENABLE PRIVACY | OK | - | Enters privacy mode (separate from SET PASSWORD, XOR password) |
| 0xBB | 64-BIT PASSWORD PROTECTION | OK | - | Requires both R+W passwords |
| 0xBC | STAY QUIET PERSISTENT | OK | - | Persistent quiet survives power cycles |
| 0xBD | READ SIGNATURE | OK | - | Returns 32-byte ECC originality signature |
Model Issues
-
Password ID 0x10 (EAS/AFI) missing— FIXED: pwd_id 0x10 now in model. -
Privacy mode behavior— FIXED: GET_RANDOM now works in privacy mode. -
ENABLE PRIVACY (0xBA) is separate— FIXED: 0xBA implemented as dedicated command with XOR password. -
16-bit counter (block 79)— FIXED:BlockAccess.write_mode="counter"in memory model, LE16 increment with 0xFFFF saturation. -
Protection pointer access conditions — datasheet defines Page L / Page H with separate read/write protection bits (Extended Protection Status byte). Model uses simpler
protection_pointerinteger. -
CC byte 3 MBREAD flag missing— FIXED: NFC Type 5 CC byte 3 was0x00(no MBREAD), causing phones to never send READ MULTIPLE BLOCKS. Real SLIX2 tags advertise0x01(MBREAD supported). Without this flag, Android NFC reads CC + system info then gives up — it won't fall back to READ SINGLE BLOCK for NDEF data. Fixed inNfcType5Tag._write_cc()for all Type 5 tags.
Implementation Priority
Completed (2026-03-17):
GET NXP SYSTEM INFO (0xAB)— model + table compilerREAD SIGNATURE (0xBD)— model + table compilerENABLE PRIVACY (0xBA)— model + table compilerEAS/AFI password (pwd_id 0x10)— model + table compilerPROTECT PAGE (0xB6)— model (write auth required) Also: Fixed 0xA1/0xA2 names (FAST INVENTORY READ / SET EAS), removed fake config registers, fixed privacy mode to allow GET_RANDOM, SET_PASSWORD uses XOR with GET_RANDOM.
Completed (2026-03-18):
6. WRITE PASSWORD (0xB4) — model (requires prior SET PASSWORD auth, XOR password)
7. LOCK PASSWORD (0xB5) — model (permanently locks password, prevents WRITE PASSWORD)
8. DESTROY (0xB9) — model (irreversibly kills tag, XOR password, no prior auth)
9. LOCK PAGE PROTECTION (0xB7) — model (permanently locks PP config, requires write auth)
10. 64-BIT PASSWORD PROTECTION (0xBB) — model (requires both read + write auth)
Completed (2026-03-18):
11. EAS subsystem (0xA2-0xA7) — SET/RESET/LOCK EAS, EAS ALARM, PASSWORD PROTECT EAS/AFI, WRITE EAS ID
12. INVENTORY READ / FAST INVENTORY READ (0xA0/0xA1) — returns UID + block data
13. STAY QUIET PERSISTENT (0xBC) — survives power cycles
Completed (2026-03-18):
14. Block 79 counter — write_mode="counter" in BlockAccess, LE16 increment with saturation at 0xFFFF
All SLIX2 commands implemented. No remaining gaps.
Cross-IC Command Scope (2026-03-18)
Full transponder audit against datasheets (SL2S2002, SL2S3003, SL2S6002, NTP5210, NTA5332, AN11809) found command scope issues in the class hierarchy:
-
SLIX (SL2S2002) had 3 excess commands — 0xAB (GET NXP SYSTEM INFO), 0xBD (READ SIGNATURE), 0xA7 (WRITE EAS ID) were dispatched at the SLIX/NxpIcodeTag level but are SLIX2+ only per SL2S2002 datasheet and AN11809. Moved dispatch to IcodeSlix2Tag.
-
NTAG 5 had STAY QUIET PERSISTENT (0xBC) but shouldn't — inherited from IcodeSlix2Tag. NTP5210 and NTA5332 datasheets omit it; feature flags confirm PERS_QUIET=0b. Blocked at Ntag5PlatformTag.
-
NTAG 5 was missing WRITE SRAM (0xD3) — NTA5332 Table 122 lists it. Added to Ntag5LinkTag.
-
NTAG 5 was missing AREA_1 password IDs (0x40/0x80) — NTP5210/NTA5332 datasheets list these. Added to Ntag5PlatformTag.
-
NTAG 5 was missing PICK RANDOM UID (0xC2) — NTA5332 datasheet 8.2.4.9.15. Added to Ntag5PlatformTag (AES mode).
See docs/plans/2026-03-18-transponder-audit-fixes.md for full audit plan.