`hw fpga config` drives the FPGA over JTAG, but on PM5 the FPGA has to be
clocked/powered first - previously that only happened as a side effect of a
reader command (e.g. `hf 14a read`), so `hw fpga config` failed if run on its
own. Bring the FPGA up in the HAL at the start of FpgaStartConfig()
(FpgaSetup24MHzClk) so the command works standalone; no doc workaround needed.
Adds an opt-in `--rgb` flag to the continuous `hf tune` / `lf tune` commands that
mirrors the antenna tuning level on the PM5 antenna RGB LED: blue = low, green =
mid, red = high, tracking the on-screen bar so you can find coupling (e.g. an
implant) by feel without watching the screen.
The colour is computed client-side from the same per-iteration voltage / running
peak the bar uses (so it matches the bar and auto-scales), and pushed to the
device via a new dumb CMD_PM5_RGB_SET {r,g,b}. That command is handled (#ifdef
PM5) by a dedicated AT32 RGB HAL module, common_arm/rgb/{rgb_apis.h,
rgb_hw_at32.c} (RgbLedSet(), I2C controller @ 0x48), wired into the armsrc
Makefile/CMake as SRC_RGB for PM5 only - so no other platform is affected and no
hardware code lands in shared files.
PM5's FPGA (Gowin GW1NR) bitstream is loaded at runtime via `hw fpga config`
and is not compiled into the firmware; only the Xilinx fpga_pm3_hf.bit is pulled
in (to generate g_fpga_version_information[]) which PM5 never runs. So the
`[ FPGA ] fpga_pm3_hf.ncd image 2s30vq100` line described a bitstream unrelated
to the actual device.
- Firmware (appmain.c): omit the [FPGA] section from the version string on PM5
(#ifndef PM5), since there's no meaningful built-in FPGA version to report.
- Client (cmdhw.c): skip the FPGA_TYPE "chip mismatch" check for PM5, which would
otherwise trigger now that the section is gone.
The [Model] section only distinguished RDV4 firmware from a "PM3 GENERIC"
else branch, so PM5 (AT32) fell through and printed "Firmware... PM3 GENERIC"
even though the banner/Target/MCU already report PM5/AT32F437. Add an IfPm5()
branch that prints "Firmware... PM5" and the external-flash status.
Note: the "[ FPGA ] ... 2s30vq100" line in hw version is separate and comes
from the firmware-generated version string (fpga_version_info.c). On PM5 the
build reuses the Xilinx fpga_pm3_hf.bit only to generate that version info
(see Makefile.hal PM5 TODO), while the real Gowin FPGA is loaded via JTAG, so
the reported bitstream name is a placeholder. Fixing that is a firmware/build
change, not addressed here.
`hw version` and `hw status` decoded the reported chip id as an Atmel AT91
CIDR. On PM5 (AT32) the id is an ARM DBGMCU IDCODE, so it showed
"MCU Unknown", a bogus flash size (32 KB / 973% used) and "PM3 GENERIC".
- Client: when IfPm5(), print MCU "AT32F437" and the real flash size, and add
a "PM5" target line, instead of running the AT91 decode.
- Firmware: the flash size can't be derived from the AT32 IDCODE, so the device
now sends GetChipFlashSize(). It is appended AFTER the version string in the
CMD_VERSION reply, so the wire layout is unchanged and it stays compatible in
both directions (old client ignores the trailing bytes; new client length-
guards and treats a missing value as 0). GetChipFlashSize() already exists for
both AT91 and AT32.
The AT32 battery-domain helper at32_bpr_write_dt1() enabled the ERTC (ertcen)
but never selected an ERTC clock source (ertcsel stayed NOCLK). Writing the
ERTC write-protection register (ERTC->wp) requires the ERTC to be clocked, so
with no source the write stalled the APB once the CPU ran at the full PLL clock
(288MHz, 144MHz APB); it only survived on the slow HICK clock.
The bootrom reaches this via check_goto_flash_mode() -> system_bpr_chk_clear()
while reading/clearing the "enter flash mode" magic the OS sets on a software
reset. That runs after ConfigSystemClocks() (the button branch needs
SpinDelayUs()/the timer clock, so the clock must be up first), i.e. at 288MHz,
so the bootrom hung and the device never re-enumerated into the bootloader
until a physical USB replug.
Fix: select the ERTC clock (HEXT/20, as the tick HAL does) before touching the
ERTC registers. HEXT is running by the time this executes, so the wp write no
longer stalls. The fix is contained in the AT32 HAL (sys_hw_at32.c, which only
builds for AT32/PM5); the shared bootrom flow and its ConfigSystemClocks()-first
ordering (needed by AT91/RDV4 SpinDelayUs) are unchanged.
Replace the hard-coded AT91 PDC register access in SniffIso14443a() with
cross-platform helpers for the RX double-buffer status/refresh, so the
sniffer no longer depends on AT91-specific registers.
- Add FPGA_SSC_DMA_RX_{Primary,Secondary}_Done and
FPGA_SSC_DMA_RX_Refresh_{Both,Secondary} to fpga_apis.h.
- AT91: primary maps to PDC RPR/RCR, secondary ("next") to RNPR/RNCR.
- AT32: no double buffer, so the primary path is a no-op and all re-arming
is done through the secondary (single-shot DMA re-arm).