Skip to content

Commit dd7509c

Browse files
committed
Add hw version echo and led control.
1 parent e0ef4fc commit dd7509c

3 files changed

Lines changed: 58 additions & 2 deletions

File tree

script/pn532_cli_unit.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from pathlib import Path
2222
from platform import uname
2323
from datetime import datetime
24-
from pn532_enum import MfcKeyType, MifareCommand, PN532KillerMode, PN532KillerTagType
24+
from pn532_enum import MfcKeyType, MifareCommand, PN532KillerMode, PN532KillerTagType, Status
2525

2626
from pn532_utils import CLITree
2727

@@ -123,6 +123,7 @@ def check_tools():
123123

124124
root = CLITree(root=True)
125125
hw = root.subgroup("hw", "Hardware-related commands")
126+
hw_led = hw.subgroup("led", "LED control commands")
126127
hw_mode = hw.subgroup("mode", "Mode-related commands")
127128
hf = root.subgroup("hf", "High-frequency commands")
128129
hf_14a = hf.subgroup("14a", "ISO 14443-A commands")
@@ -1342,6 +1343,38 @@ def on_exec(self, args: argparse.Namespace):
13421343
print("Failed to get firmware version")
13431344

13441345

1346+
@hw_led.command("on")
1347+
class HWLedOn(DeviceRequiredUnit):
1348+
def args_parser(self) -> ArgumentParserNoExit:
1349+
parser = ArgumentParserNoExit()
1350+
parser.description = "Turn on PN532Killer LED"
1351+
return parser
1352+
1353+
def on_exec(self, args: argparse.Namespace):
1354+
if self.device_com.get_device_name() != "PN532Killer":
1355+
print("LED control is only supported on PN532Killer.")
1356+
return
1357+
resp = self.cmd.led_on()
1358+
ok = resp.parsed if hasattr(resp, "parsed") else (resp.status == Status.SUCCESS)
1359+
print(f"LED on: {'Success' if ok else 'Fail'}")
1360+
1361+
1362+
@hw_led.command("off")
1363+
class HWLedOff(DeviceRequiredUnit):
1364+
def args_parser(self) -> ArgumentParserNoExit:
1365+
parser = ArgumentParserNoExit()
1366+
parser.description = "Turn off PN532Killer LED"
1367+
return parser
1368+
1369+
def on_exec(self, args: argparse.Namespace):
1370+
if self.device_com.get_device_name() != "PN532Killer":
1371+
print("LED control is only supported on PN532Killer.")
1372+
return
1373+
resp = self.cmd.led_off()
1374+
ok = resp.parsed if hasattr(resp, "parsed") else (resp.status == Status.SUCCESS)
1375+
print(f"LED off: {'Success' if ok else 'Fail'}")
1376+
1377+
13451378
@hf_sniff.command("setuid")
13461379
class HfSniffSetUid(DeviceRequiredUnit):
13471380
def args_parser(self) -> ArgumentParserNoExit:

script/pn532_cmd.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,28 @@ def get_firmware_version(self):
571571
resp = self.device.send_cmd_sync(
572572
Command.GetFirmwareVersion, None, Status.SUCCESS, 1
573573
)
574-
resp.parsed = f"Ver.{resp.data.hex()}"
574+
version_hex = resp.data.hex()
575+
resp.parsed = f"Ver.{version_hex}"
576+
577+
# PN532Killer encodes the last three bytes as YY MM DD; surface a friendlier date string.
578+
if len(resp.data) >= 4 and self.device.get_device_name() == "PN532Killer":
579+
ic = resp.data[0]
580+
year, month, day = resp.data[1:4]
581+
resp.parsed = f"Ver.{version_hex} (IC 0x{ic:02X}, Date {year:02d}-{month:02d}-{day:02d})"
582+
return resp
583+
584+
def led_on(self):
585+
if self.device.get_device_name() != "PN532Killer":
586+
raise ValueError("LED control is only supported on PN532Killer")
587+
resp = self.device.send_cmd_sync(Command.WriteGPIO, b"\x00\x01")
588+
resp.parsed = resp.status == Status.SUCCESS
589+
return resp
590+
591+
def led_off(self):
592+
if self.device.get_device_name() != "PN532Killer":
593+
raise ValueError("LED control is only supported on PN532Killer")
594+
resp = self.device.send_cmd_sync(Command.WriteGPIO, b"\x00\x00")
595+
resp.parsed = resp.status == Status.SUCCESS
575596
return resp
576597

577598
@expect_response(Status.SUCCESS)

script/pn532_enum.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class Pn532KillerCommand(enum.IntEnum):
7474
"HWModeReader",
7575
"HWModeSniffer",
7676
"HWModeEmulator",
77+
"HWLedOn",
78+
"HWLedOff",
7779
"HF15Scan",
7880
"HF15Info",
7981
"HF15Rdbl",

0 commit comments

Comments
 (0)